Получение URI данных для междоменного контента?

Предположим, у меня есть веб-страница с полем ввода, где пользователи могут ввести URL-адрес изображения, нажать кнопку и получить URI данных для ресурса на другом конце своего URL-адреса (например, логотип Google ).

Читая вокруг, я узнал, что вы можете получить URI данных для изображений следующим образом:

function imageToDataURI(src,callback)
{
    var canvas = document.createElement('canvas'),
        img    = document.createElement('img');

    img.onload = 
        function()
        {
            canvas.width  = img.width;
            canvas.height = img.height;
            canvas.getContext('2d').drawImage(img, 0, 0);
            callback(canvas.toDataURL());
        };
    img.src = src;
}

Однако многие люди (включая меня) получают сообщение «SECURITY_ERR: DOM Exception 18», потому что элементы холста испорчены, когда на них нарисованы междоменные изображения, а испорченные холсты возвращают указанную выше ошибку на canvas.toDataURL () (см. Почему canvas.toDataURL () выдает исключение безопасности?). Моя проблема: мне действительно нужно поддерживать междоменные URL!

Что я могу сделать?


person rmanna    schedule 20.07.2012    source источник


Ответы (1)


Я прочитал о множестве доступных вариантов получения междоменных данных здесь. Есть три категории решений:

  1. те, которые создают огромные дыры в безопасности на вашей веб-странице
  2. те, которые этого не делают, но требуют управления междоменным сервером
  3. те, которые требуют, чтобы вы превратили собственный сервер в прокси

Если вы не можете позволить себе №1, находитесь не в №2 и имеете в своем распоряжении сервер node.js, вот суперпростой модуль node.js с поддержкой plug-and-play, который подойдет для №3.

/* return a datauri encoding of the resource at the given url */
exports.dataurize = 
    function(url,callback)
    {
        var request = 
            require('http').request(
                {'host':url.host || 'localhost', 
                 'port':url.port || 80, 
                 'path':url.path || '/'},
                function(resp)
                {
                    var data = '';
                    resp.setEncoding('binary');
                    resp.on('data', function(chunk) {data += chunk;});
                    resp.on('end',
                        function()
                        {
                            if( resp.statusCode == 200 )
                                callback(
                                    undefined,
                                    'data:'+resp.headers['content-type']+';base64,'+
                                       new Buffer(data,'binary').toString('base64'));
                            else
                                callback({'statusCode':resp.statusCode, 'reason':data});
                        });
                });
        request.on('error',
            function(err)
            {
                callback({'statusCode':0, 'reason':err});
            });

        request.end();
    };

Интегрируйте его в свой бэкэнд, и вы будете дома бесплатно для №3. Возвращаясь к исходной проблеме, imageToDataURI () теперь запрашивает ваш сервер node.js с URL-адресом, и ваш сервер отвечает результатом

require('./dataurize').dataurize(...) 

то есть с желаемым dataURI.

person rmanna    schedule 20.07.2012