仅当预加载图像时 canvas 才会出现 CORS 问题

CORS issue with canvas only when image is preloaded

我的问题只有在加载的图像预加载到其他地方时才会出现。例如,当我在某处使用带有 src 属性的 <img> 标签时。

看看这段代码:

 <canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;" ></canvas>
 
 <img src="https://local-spaces.fra1.digitaloceanspaces.com/test.jpg" width="50"/>
 
 <button onclick="show()">Load Canvas Picture</button>
 
 <script>
function show() {
   const c = document.getElementById("myCanvas");
    const ctx = c.getContext("2d");

    const img = new Image();
    img.setAttribute('crossOrigin', 'anonymous');


    img.onload = function(){
      ctx.drawImage(img,0,0, 300, 150);
    };
  
    img.src = "https://local-spaces.fra1.digitaloceanspaces.com/test.jpg"
   
}
</script>

注意:如果您在 canvas 中正确看到图像,请缓存+硬重新加载您的浏览器以查看错误。

如果您单击该按钮并打开您的控制台,您将看到您得到 CORS-error:

Access to image at 'https://local-spaces.fra1.digitaloceanspaces.com/test.jpg' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

现在让我们看下一个例子,看看它在没有预加载图像的情况下工作:https://jsfiddle.net/akzxp9vs/

注意:要使此示例正常运行,删除缓存并重新加载浏览器非常重要。

只有这样你才能看到正确的 header 响应正在回馈。

有什么办法吗?

图片在Digital Ocean的S3 Cloud上,叫做Spaces。图像本身设置为 public 并且 CORS 设置设置为:

浏览器需要知道在发出 HTTP 请求时检查 CORS 权限(即包含 Origin header 等)。

当您创建新的 Image object 时,它会使用来自 <img> 元素的缓存数据。

向现有 <img> 元素添加 crossorigin 属性或完全删除该 <img> 元素。

我找到了解决问题的更好方法。 @Quentin 的解决方案基本上是正确的,但它不可行。我试图更新所有 <img>-标签,但是在我的页面中我有许多包也在使用 <img>-标签。

例如传单。它类似于 Google 地图,但带有开放式街道地图。您只是无法控制在自定义图标中设置 crossorigin 等属性。

所以必须有另一种解决方案。使用起来感觉很糟糕,但它确实有效。

const src = new URL(imgUrl);
src.searchParams.append('cors', Date.now());
return src.href;

此代码附加到您的 URL 查询参数并强制 Chrome 重新加载图像而不缓存。