画布上的 CORS 在 Chrome 和 Safari 上不起作用

Posted

技术标签:

【中文标题】画布上的 CORS 在 Chrome 和 Safari 上不起作用【英文标题】:CORS on canvas not working on Chrome and Safari 【发布时间】:2018-06-29 05:53:31 【问题描述】:

我正在尝试在画布上显示图像。图像托管在 S3 上。

在AWS上设置了CORS,脚本中CrossOrigin属性设置为anonymous

在 Firefox 上一切正常——但图像无法在 Chrome 和 Safari 上加载。

Safari 错误:

Origin https://www.example.com 不允许 访问控制允许来源。 http://mybucket.s3.amazonaws.com/bubble/foo.PNG

[错误] 加载资源失败:Origin https://www.example.com 不是 Access-Control-Allow-Origin 允许。 (foo.PNG,第 0 行)

跨域资源共享拒绝跨域图像加载 政策。

Chrome 错误:

通过“https://mybucket.s3.amazonaws.com/bubble/foo.PNG”访问图像 来自原点“null”已被 CORS 策略阻止:否 'Access-Control-Allow-Origin' 标头出现在请求的 资源。因此,不允许访问 Origin 'null'。

CORS 配置非常标准。我尝试了<AllowedOrigin>*</AllowedOrigin> 和其他几个变体,但没有任何区别……除了一个例外:<AllowedOrigin>null</AllowedOrigin> 似乎适用于 Chrome。

AWS 上的 CORS 配置

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://www.example.com</AllowedOrigin>
    <AllowedOrigin>http://www.example.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>

画布脚本

let myImage = new Image();
myImage.setAttribute('crossOrigin', 'anonymous');

myImage.src = thisDocument.url;
myImage.onload = function() 
  canvas = document.getElementById('myCanvas');
  context = canvas.getContext('2d');

  canvas.setAttribute('width', 200);
  canvas.setAttribute('height', 200);

  context.fillStyle = hsl(0, 50%, 50%);
  context.fillRect(0, 0, 120, 120);
  context.drawImage(myImage, 12, 12, 60, 60);
;

【问题讨论】:

origin 'null' != http[s]://example.com 来自您允许的来源。我猜origin 'null' 表示您正在以http://localhost 的身份进行测试? 不幸的是,事实并非如此。 :( 该应用程序在 Meteor 的 Galaxy (Docker/AWS) 上运行,图像托管在 S3 上。 解决办法是什么?请查看***.com/questions/60024200/… 【参考方案1】:

我有一个非常相似的问题(在 Safari 和 Chrome 上使用带有访问控制错误的 S3 托管)。

它最终成为特定于 Chrome 和 Safari 的缓存问题。如果您通过 CSS 或 &lt;img&gt; 标签加载图像,则该图像将被缓存而没有 Access-Control-Allow-Origin 标头。

您可以通过禁用缓存并检查错误是否仍然存在来检查您是否属于这种情况。如果是这个问题,这个答案可能会有所帮助:Refresh image with a new one at the same url

【讨论】:

看来你是对的。当开发者窗口打开并且缓存被(无意中)禁用时,图像已经加载。 我有同样的问题,但我想在我的网站中使用缓存,我们如何缓存带有 access-control-allow-origin 标头的图像?你能解释一下吗? 我以为我快疯了,直到我找到这个答案 - 我页面上的 img 标签中使用了相同的图像。我通过在我的 javascript 中使用将 ?canvas=true 添加到 url 来解决此问题,然后将其视为单独的图像。

以上是关于画布上的 CORS 在 Chrome 和 Safari 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

我应该在哪里设置 CORS 设置,这样我的画布才不会被污染?

crossOrigin 属性与 Chrome 上的外部图像检索混淆

Android Chrome 上的 HTML 画布不滚动窗口

移动 Chrome 上的 CORS Allow-Access-Control-Origin

HTML5 Draggable setDragImage 不适用于 Chrome 上的画布

CORS 已启用,但 toDataURL 仍会引发警告