为什么使用HTML Canvas在图像上使用CORS?

时间:2016-01-26 17:39:13

标签: javascript html5 canvas cors

最近,我花了一些时间研究解决Web开发中一个相当常见的问题的解决方案 - 我在透明背景上处理中间对齐的徽标,但是必须在它们下面放置文本,它会显得好像文本和图像之间的空白量在页面之间移动。经过一些研究,我发现我可以使用画布重新对齐左下图像,并且解决方案工作得很漂亮......至少直到我将解决方案集成到我们的代码库中并发现它失败了: / p>

"无法从画布获取图像数据,因为画布已被跨源数据污染。" (说什么!?)

调查一下,违规代码位于以下函数的第一行:

getColumn: function (context, x, y, imageHeight) {
    var arr = context.getImageData(x, y, 1, imageHeight).data; //<-- CORS HATES THIS!
    return pvt.normalizeRGBArray(arr)
}

现在,我完全理解CORS标准是什么,我知道这个问题的解决方案。服务器需要首先支持CORS。服务器可以设置http标头access-control-allow-origin:&#34; *&#34;,或允许开发人员将图像的crossDomain属性设置为&#34;匿名&#34; /&# 34;使用的凭证&#34 ;.这一切都很好,花花公子,除非你在一家大公司的前端工作,说服服务器领主改变与安全相关的任何事情是一个非首发性的对话。

所以,我的问题是,在画布上的图像中出现此安全错误背后的逻辑是什么?他们是frickin&#39;大声喊叫的图像!可以下载它们,热链接到它们,在内存中使用它们,但是不能!&#34;不要以任何方式操纵它们,否则CORS会抛出错误!

如果你问我,图像没有被污染,那就是这个头发的CORS标准。有人可以解释为什么会发生这种情况的逻辑吗?如何使用画布操作图像可能是一个安全问题?

2 个答案:

答案 0 :(得分:3)

  

这可以防止用户在未经许可的情况下使用图像从远程网站提取信息来暴露私有数据。

来源:MDN

答案 1 :(得分:1)

很抱歉,不是问题的答案,而是......

仅供参考:这不是

  

服务器可以设置http标头access-control-allow-origin:“*”,或允许开发人员将图像的crossDomain属性设置为“anonymous”/“use-credentials”。

需要

您需要设置crossOrigin,因为它会更改浏览器对图像服务器的请求。但即使您没有设置它,服务器也会发送CORS标头,除非您设置了crossOrigin,否则浏览器仍然不允许您使用该图像。

您可以在此示例中看到两个图像,这两个图像都从服务器接收CORS标头,但浏览器只允许一个工作。

loadAndDrawImage("https://i.imgur.com/fRdrkI1.jpg", "");
loadAndDrawImage("https://i.imgur.com/Vn68XJQ.jpg");

function loadAndDrawImage(url, crossOrigin) {
  const img = new Image();
  img.onload = function() { 
    log("For image", crossOrigin !== undefined ? "WITH" : "without", "crossOrigin set");
    try {
      const ctx = document.createElement("canvas").getContext("2d");
      ctx.drawImage(img, 0, 0);
      ctx.getImageData(0, 0, 1, 1);
      log("canvas still clean:", name);
    } catch (e) {
      error(name, ":", e);
    }
    log(" ");
  };  
  if (crossOrigin !== undefined) {
    img.crossOrigin = crossOrigin;
  }
  img.src = url;
}

function logImpl(color, ...args) {
  const elem = document.createElement("pre");
  elem.textContent = [...args].join(" ");
  elem.style.color = color;
  document.body.appendChild(elem);
}

function log(...args) {
  logImpl("green", ...args);
}

function error(...args) {
  logImpl("red", ...args);
}
pre { margin: 0; }
<div>check headers in devtools</div>

如果您检查标题,您会看到它们都收到了CORS标题,但只有一个图像有效。

enter image description here

enter image description here