1
<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.

为什么以及如何解决?

4

1 回答 1

3

在当前的 Chromium 实现中,总是CSSImageValue::WouldTaintOrigin设置为 return 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作为潜在来源,但计划是它将属于is-origin-clean算法的HTMLOrSVGImageElement分支。所以CSSImageValue应该只在跨域请求的情况下污染画布,但是考虑到 API 的年轻以及在所有这些经常变化的接口中存储这些信息的难度,实现者只是在安全方面犯了错误,只是简单地标记它一直都是不安全的,因为他们被允许使用他们认为不安全的任何来源。

于 2020-05-31T04:03:03.383 回答