Получавате 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 се повреждат, когато върху тях се рисуват изображения от различни домейни, а повредените платна връщат горната грешка на canvas.toDataURL() (вижте Защо canvas.toDataURL() хвърля изключение за сигурност?). Моят проблем е: наистина трябва да поддържам кръстосани URL адреси!

Какво мога да направя?


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


Отговори (1)


Прочетох за куп налични опции за получаване на данни от различни домейни тук. Има почти 3 категории решения:

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

Ако не можете да си позволите #1, не сте в #2 и имате node.js сървър на ваше разположение, ето един супер прост plug-and-play node.js модул, който ще направи #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