javascript - 即使带有 CORS header ,HTML Canvas 也会受到污染

标签 javascript image canvas cors

我正在尝试获取图像的数据 URL。该图像来自跨源远程服务器维基百科。我使用这个 JavaScript 来尝试这样做:

# get the image
const img = document.createElement('img')
img.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Strychnine.svg/360px-Strychnine.svg.png'
# don't send credentials with this request
img.crossOrigin = 'anonymous'
# now copy to a <canvas /> to get data URL
const canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
const ctx  = canvas.getContext('2d')
ctx.drawImage(img, 0, 0)
canvas.toDataURL('image/jpg')

但我收到此错误:Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvass may not be exported

我读到这是一个 CORS 问题。如果服务器未设置 Access-Control-Allow-Origin header ,浏览器会阻止您从图像中获取图像数据。 但奇怪的是。我检查了响应并设置了标题。所以我不明白为什么这不起作用。这是我从终端发出请求时的输出( header 与 Chrome devtools 中显示的相同)。

$ http 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Strychnine.svg/360px-Strychnine.svg.png'

HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish
Age: 6359
Connection: keep-alive
Content-Disposition: inline;filename*=UTF-8''Strychnine.svg.png
Content-Length: 11596
Content-Type: image/png
Date: Fri, 29 Dec 2017 21:00:31 GMT
Etag: 223fb180fc10db8693431b6ca88dd943
Last-Modified: Sun, 04 Sep 2016 09:13:24 GMT
Strict-Transport-Security: max-age=106384710; includeSubDomains; preload
Timing-Allow-Origin: *
Via: 1.1 varnish-v4, 1.1 varnish-v4, 1.1 varnish-v4, 1.1 varnish-v4
X-Analytics: https=1;nocookies=1
X-Cache: cp1049 hit/4, cp2022 pass, cp4026 hit/4, cp4024 hit/3
X-Cache-Status: hit-front
X-Client-IP: 2606:6000:670c:f800:989:be22:e59d:3c3f
X-Object-Meta-Sha1Base36: 1xx5tvhafvp54zfrfx5uem0vazzuo1a
X-Timestamp: 1472980403.52438
X-Trans-Id: tx154e595e211c449d95b3d-005a469417
X-Varnish: 474505758 476375076, 160459070, 709465351 725460511, 931215054 920521958

那么为什么这不起作用?是否需要其他的东西来让我的 Canvas 不被“污染”?

最佳答案

当您在图像上设置 src 时,浏览器会请求图像。但是此时,您还没有设置 img.crossOrigin。将 img.crossOrigin 行移动到 img.src 行上方。

这解决了受污染的 Canvas 问题,但您仍然无法获得您的 URL。图像请求是异步的。您正在尝试使用尚未加载的图像绘制到 Canvas 。将其余代码移动到图像上的 load 处理程序中,并将 img.src 行放在最后以启动整个过程:

const img = document.createElement('img');
img.crossOrigin = 'anonymous';
img.addEventListener('load', () => {
  const canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  console.log(canvas.toDataURL('image/jpg'));
});
img.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/Strychnine.svg/360px-Strychnine.svg.png';

关于javascript - 即使带有 CORS header ,HTML Canvas 也会受到污染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48030496/

相关文章:

javascript - HTML5 Canvas translate(0.5,0.5) 未修复线条模糊

java - 在图像上写入文本时出错

javascript - 宽度在 jquery 中返回 0

javascript - 用纯JS和for循环滑动 Accordion

php - acf,从字段获取缩略图大小的图像

image - 颜色图显示灰度图像之间的差异

javascript - 在 JQuery 验证错误时更改输入类 [type=text]

javascript - NodeJs 使用 ExpressJs : TypeError: string is not a function at Function. app.render

java:如何调整包含图像的框架的大小

javascript - HTML5 动态创建 Canvas