canvas.toDataURL() 抛出安全异常,尽管图像是本地的
Posted
技术标签:
【中文标题】canvas.toDataURL() 抛出安全异常,尽管图像是本地的【英文标题】:canvas.toDataURL() throws security exception, despite image being local 【发布时间】:2012-04-28 13:27:48 【问题描述】:这是我处理向画布添加图像的代码。这样做是创建一个 Uploadify 实例,它将 SVG 文件上传到本地 [root]/uploads 文件夹。然后它将该图像广告到三个不同尺寸的画布上。绝不会使用 http:// 地址引用图像。所有对图像路径的引用都是 local 相对的。
var folder = '/uploads';
var fullpath = folder + '/' + $('input#canonical').val() + ".svg";
$('#file_upload').uploadify(
'uploader': '/uploadify/uploadify.swf',
'script': '/uploadify/uploadify.php',
'cancelImg': '/uploadify/cancel.png',
'folder': folder,
'fileExt': '*.svg',
'fileDesc': 'SVG files',
'scriptData': 'rename': $('input#canonical').val() + ".svg",
'onAllComplete': function()
$('#upload-wrap').hide();
var img = new Image();
img.onload = function()
var ar = img.width / img.height;
var swidth = ( ar >= 1 ) ? small : small * ar;
var mwidth = ( ar >= 1 ) ? medium : medium * ar;
var lwidth = ( ar >= 1 ) ? large : large * ar;
var sheight = ( ar <= 1 ) ? small : small / ar;
var mheight = ( ar <= 1 ) ? medium : medium / ar;
var lheight = ( ar <= 1 ) ? large : large / ar;
var sc = sCanvas.getContext('2d');
var mc = mCanvas.getContext('2d');
var lc = lCanvas.getContext('2d');
scObj.css(width:swidth, height: sheight);
mcObj.css(width:mwidth, height: mheight);
lcObj.css(width:lwidth, height: lheight);
sc.drawImage(img,0,0,swidth,sheight);
mc.drawImage(img,0,0,mwidth,mheight);
lc.drawImage(img,0,0,lwidth,lheight);
;
img.src = fullpath;
);
当我尝试调用 canvas.toDataUrl() 时,我在控制台中收到 Uncaught Error: SECURITY_ERR: DOM Exception 18
问题。有没有办法来解决这个问题?如果您需要更多信息,请告诉我。
【问题讨论】:
使用 file:// 可能是问题所在,见 [***.com/questions/2704929/… [1]: ***.com/questions/2704929/… @danwellman - 本地,我指的是同一台服务器的本地,而不是我实际的本地机器。没有发出外部 http 请求。 @Jake:那么你的意思是“相对”,而不是“本地”。 @AndyE 是的,我做到了。糟糕! 【参考方案1】:这与此处描述的问题相同:Rasterizing an in-document SVG to Canvas
基本上,将任何 SVG 添加到画布都会污染画布,并且无法再在其上调用 toDataURL()。显然,Firefox 12 修复了这个问题,但 Chrome 还没有修复它。
【讨论】:
【参考方案2】:在任何时候都不会使用 http:// 地址引用图像。对图像路径的所有引用都是本地的。
这就是问题所在。您不能以这种方式使用本地文件。这里有一点关于understanding the Canvas image security rules.
如果允许画布将本地文件绘制到自身,那么它可能会绘制本地驱动器上的文件(您私有),获取其 imageData,并将该文件上传到服务器,从而有效地窃取图像。我们不能这样,所以“本地文件破坏原始清理”规则已经到位。
您实际上可以在 Chrome 中关闭该规则:
C:\Users\theUser\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files
但这应该只用于调试。
【讨论】:
本地是指服务器本身的本地。你的评论还适用吗?我可以通过绝对引用而不是相对引用来解决它吗? 相对引用应该没问题,只要有问题的 url 具有与运行 JS 的页面相同的域和协议。那里有差异吗? (我肯定会console.log(fullpath)
)以上是关于canvas.toDataURL() 抛出安全异常,尽管图像是本地的的主要内容,如果未能解决你的问题,请参考以下文章
iOS 上的 Safari 在调用 canvas.toDataURL 时抛出 SECURITY_ERR: DOM Exception 18