首页 > 解决方案 > 在加载图像之前将 crossorigin="anonymous" 添加到所有 img 标签

问题描述

我的画布抛出错误时遇到问题,因为它试图加载此处描述的缓存图像: https ://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image

为了解决这个问题,我想添加crossorigin="anonymous"到我网站上的所有图像中,但是在加载图像之前我怎么能做到这一点,以便它们加载正确的标题,不会使我的画布崩溃?

$('img').each(function() {
     var $img = $(this);
     $img.attr('crossorigin',anonymous);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img width="50%" src="https://ychef.files.bbci.co.uk/1600x900/p08ysrxd.webp">

标签: javascripthtml5-canvascors

解决方案


您正在做的方式应该有效(在修复语法错误之后),您必须crossOrigin在下一个microtask checkpoint之前处理属性的设置,这意味着您必须同步进行,而不是在异步脚本或事件处理程序中。

然而,浏览器并不总是遵循这个规则,在某些情况下,缓存图像的加载可以同步完成。因此,为避免出现这种情况,您可以简单地将其设置src为相同的值,以强制浏览器使用正确的标头加载资源。

$('img').each(function() {
  var $img = $(this);
  $img.attr({
    crossorigin: "anonymous",
    src: this.src
  });
});

// test we loaded it with the proper headers
$(window).on("load", () => {
  const canvas = document.createElement("canvas");
  canvas.getContext("2d").drawImage($('img')[0], 0, 0);
  console.log('cross-origin enabled', !!canvas.toDataURL());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img width="50%" src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">

但是在您的位置上,我会仔细检查为什么此时需要这样做,正确的解决方法显然是从头开始设置属性:

// test we loaded it with the proper headers
window.onload = () => {
  const canvas = document.createElement("canvas");
  canvas.getContext("2d").drawImage( document.querySelector('img'), 0, 0);
  console.log('cross-origin enabled', !!canvas.toDataURL());
};
<img crossorigin="anonymous" width="50%" src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png">

但是请注意,您问题中的图像Vary: Origin仅在作为跨域请求时才由 Amazon S3 提供标头,这将使 Chrome 仍使用缓存版本,即使crossOrigin设置了属性,请参阅此 Q/A 了解更多信息.

在这种情况下,唯一的方法是始终设置crossOrigin属性。


推荐阅读