就所有意图和目的而言,假设我有一个带有输入字段的网页,用户可以在其中输入图像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.to DataURL()会引发安全异常?)。我的问题是:我真的需要支持跨域URL!
我能做什么?
我在这里读到了一堆用于获取跨域数据的可用选项。几乎有三类解决方案:
- 那些在你的网页上制造巨大安全漏洞的人
- 那些不需要但需要控制跨域服务器的
- 那些需要您将自己的服务器变成代理的
如果你负担不起#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(...)
即具有期望的数据URI。