获取跨域内容的数据URI?

时间:2012-07-20 04:17:35

标签: javascript node.js canvas cross-domain data-uri

出于所有意图和目的,假设我有一个带有输入字段的网页,用户可以在其中输入图像URL,单击按钮,并在其URL的另一端为该资源提供数据URI(例如,谷歌徽标)。

阅读,我了解到你可以获得图像的数据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元素会受到污染(见Why does canvas.toDataURL() throw a security exception?)。我的问题是:我真的需要支持跨域URL!

我该怎么办?

1 个答案:

答案 0 :(得分:1)

我阅读了大量有关获取跨域数据here的可用选项。有三类解决方案:

  1. 那些在您的网页上造成巨大安全漏洞的内容
  2. 那些不需要但需要控制跨域服务器的人
  3. 要求您将自己的服务器变为代理的
  4. 如果你买不起#1,不在#2,并且有一个node.js服务器可供你使用,这里是一个超级简单,即插即用的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()现在用你的url查询你的node.js后端,你的后端用

    的结果作出响应
    require('./dataurize').dataurize(...) 
    

    即,使用所需的dataURI。