【问题标题】:The canvas has been tainted by cross-origin data with computedStyleMap().get("background-image")画布已被带有 computedStyleMap().get("background-image") 的跨域数据污染
【发布时间】:2020-09-17 00:52:57
【问题描述】:
<div id='img3'>background-image with this</div>
#img3 {
  background-image: url("../icons/we-flow.png");
}
var img = img3.computedStyleMap().get("background-image");
//img=img1;
var canvas=document.createElement('canvas');
img.crossOrigin="Anonymous";
var ctx=canvas.getContext('2d');
try {
  ctx.drawImage(img, 0, 0);
  var data=ctx.getImageData(0, 0, canvas.width, canvas.height).data;
}catch (error) {
  console.log('refresh page will get this', img.toString(), {error, img});
}

用chrome 83运行这段代码,第一次加载代码,一切正常,但是当我在浏览器中刷新页面时,我得到了console.log:

DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.

为什么以及如何解决?

【问题讨论】:

    标签: javascript google-chrome canvas background-image cssom


    【解决方案1】:

    在当前的 Chromium 实现中,CSSImageValue::WouldTaintOrigin 始终设置为返回 true

    https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/css/cssom/css_style_image_value.h#L32

     bool WouldTaintOrigin() const final { return true; }
    

    如果您在画布上绘制了这样的图像源后能够获取画布数据,请立即向 chromium 团队提交错误,因为这将是一个安全问题。 (但我无法在我自己的 Chrome 83 或任何其他分支上重现此内容)。

    请注意,目前的 HTML 规范仍然没有将 CSSImageValue 作为潜在来源,但the plan 是它将属于 is-origin-cleanHTMLOrSVGImageElement 分支算法。所以 CSSImageValue 应该只在跨域请求的情况下污染画布,但考虑到 API 的年轻化以及将这些信息存储在所有这些经常变化的接口中的困难,实现者只是犯了错误通过简单地将其始终标记为不安全来表明安全的一面,因为他们可以对任何他们认为不安全的来源进行处理。

    【讨论】:

    • 非常感谢,我的实验支持你的观点,只要把对应的网址转成图片,就不会污染画布了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 2020-01-03
    • 2014-04-01
    相关资源
    最近更新 更多