在画布上调用 toDataUrl 时 IE 引发安全错误

Posted

技术标签:

【中文标题】在画布上调用 toDataUrl 时 IE 引发安全错误【英文标题】:IE throws Security Error when calling toDataUrl on canvas 【发布时间】:2013-12-17 20:00:07 【问题描述】:

首先,我知道当源图像来自另一个来源时访问画布的toDataURL 方法是一个安全问题。

但就我而言,我使用data: url 作为我的img 的来源,然后使用img 并将其绘制在canvas 上,然后调用canvas.toDataUrl

这在 Chrome 和 Firefox 上运行良好,但在 IE 中失败并出现安全错误!

有什么想法吗?

...
var svgxml = getxmlsvg();
img.onload = function()
    canvas.drawImage(this, 0, 0);
    canvas.toDataURL("image/png"); // <--- security error

image.src = URL.createObjectURL(new Blob([svgxml], type: "image/svg+xml;charset=utf-8" ))

这是svgopen.org的引述

将数据从 SVG 传输到 Canvas 存在安全问题,这会导致 画布变为只写。我们认为这些问题可能是 避免使用我们的 SVG.toDataURL() 提案(“建议”部分)。

Same Origin 和 Canvas Origin 政策

网页由来自不同的不同元素组成 起源。来自同一来源的元素被认为是 安全 [Origin10]。

Canvas 具有强大的图像读写能力。它会 使用画布作为中间人将本地图像传输到 第三方只需从 file:// 将图像加载到 Canvas 元素中 -URL,然后使用 javascript 将像素数据从 Canvas 元素发送到任何主机。

为了防止 Canvas 的信息泄露,浏览器会小心 当图像数据的来源不是时保护 Canvas 的使用 安全的。所有 Canvas 元素都作为它们的 origin-clean 属性创建 设置为真。当任何可能被用于 使用 Canvas 元素传输违反同源的内容 策略,origin-clean 属性永久设置为 false。

If 方法返回存储在画布中的像素数据,例如 toDataURL() 或 getImageData(),在 Canvas 元素上调用 origin-clean 为 false,则引发 DOMException 18 SECURITY_ERR [画布10]。

但我正在浏览器中动态创建 SVG。

【问题讨论】:

听起来像是 IE 中的错误...这是什么版本的 IE? 我想是的,我使用的是 IE 11。我不记得正确但似乎是因为在画布上绘制 svg 图像使其成为 write-only!并防止进一步的读取操作!我已经更新了问题。 IE 具有时髦的隐私/安全级别,不一定与其他浏览器一致。在追查这是否是 IE 中的错误之前,请尝试将它们降低到最低限度 @Bakhshi:你读过你找到的整个文件吗?它似乎包含您正在寻找的答案:“SVG 可能包含来自多个来源的内容,并且浏览器倾向于将任何具有 MIME 类型 image/svg+xml 的内容列入黑名单作为多来源内容,甚至无需测试实际内容. […]" 虽然Webkit has been fixed 在此期间,IE 似乎仍然表现出这种行为 是的,你是对的@Bergi。似乎将我的 svg 呈现为 png 的唯一选择是canvg,这是我试图避免的。 【参考方案1】:

就我而言,我将构成图像的图形元素从 svg 更改为 png。使用 svg 时,当我使用 toDataURL 时,我在 IE 11(和 10)而不是 Chrome 中看到安全错误。使用 png 元素构建图形,很好。

在 IE 11 中 svgs 无法正确调整大小存在第二个问题,因此这是对在 IE 中使用 svgs 的另一个打击。

【讨论】:

有解决办法吗?从 svg 获取数据 uri png 面临同样的问题。【参考方案2】:

存在一个抽象 svg --> canvas --> png 并向 SVG 元素添加方法的库,因此在任何浏览器中,您都可以使用回调和选项“canvg”调用 mySvg.toDataUrl() :

https://github.com/sampumon/SVG.toDataURL

此实现考虑了安全异常,因此您可以克服遇到的权限错误。

<script type="text/javascript" src="http://canvg.github.io/canvg/rgbcolor.js"></script> 
<script type="text/javascript" src="http://canvg.github.io/canvg/StackBlur.js"></script>
<script type="text/javascript" src="http://canvg.github.io/canvg/canvg.js"></script> 
<script>
<script type="text/javascript" src="http://rawgit.com/sampumon/SVG.toDataURL/master/svg_todataurl.js"></script>

mySVGelement.toDataURL("image/png", 
  renderer: "canvg"
  callback: function(data) 
      image.src = data;
  
);
</script>

兼容性

Browser     E x p o r t i n g  f o r m a t
            SVG+XML  PNG/canvg  PNG/native
IE           9+       9+         -
Chrome       +        +          33+ ²
Safari       +        +          -
Firefox      +        +          11+ ¹
Opera        +        +          -

【讨论】:

不适用于 ie11。我在这里试过:sampumon.github.io/SVG.toDataURL/butterfly_test.html

以上是关于在画布上调用 toDataUrl 时 IE 引发安全错误的主要内容,如果未能解决你的问题,请参考以下文章

Canvas.toDataURL() 适用于除 IE10 以外的所有浏览器

canvas.toDataURL() 导致安全错误

画布 toDataUrl 没有在最新的 safari 上返回正确的图像

canvas.toDataURL() 用于大画布

toDataURL() 小屏幕,小保存图片

Konva stage.toDataUrl()是不是渲染我在画布中看到的图像?