从浏览器缓存提供图像时,AWS S3 + CloudFront 会出现 CORS 错误

Posted

技术标签:

【中文标题】从浏览器缓存提供图像时,AWS S3 + CloudFront 会出现 CORS 错误【英文标题】:AWS S3 + CloudFront gives CORS errors when serving images from browser cache 【发布时间】:2016-02-24 19:02:55 【问题描述】:

如果我清除浏览器缓存,加载的所有内容都会从支持云端的 S3 存储桶中找到。但是,当我关闭缓存时,控制台中出现错误:

来源 [ORIGIN URL] 的图像已被跨域资源共享策略阻止加载:请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin [MY LOCALHOST ADDRESS] 因此不允许访问。

我的 CORS 配置:

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

不久前我也遵循了这个建议并更改了 cloundfront 发行版设置。它似乎在当时有效,但现在绝对不适用于浏览器缓存: CORS problems with Amazon S3 on the latest Chomium and Google Canary

我还尝试在我的网站 .htaccess 中添加“Header add Access-Control-Allow-Origin "*"”。没有运气。注意:我的网站是从 localhost 托管和访问的(它是一个开发环境)。

【问题讨论】:

在您更新 S3 CORS 配置之前,CloudFront 是否缓存了对象? 我已经好几个月没有更改 CORS 配置了。这个问题开始在 Chrome 中自发发生。 【参考方案1】:

我发现自己遇到了同样的问题:没有 Access-Control-Allow-Origin 出现。这是非常随机的,有时有效,有时无效。我终于通过这种方式缩小了范围:

    已启用 S3 网站托管 针对 S3 和 CloudFront 中的 CORS 标头进行了测试

以下是如何轻松测试 CORS 标头:

curl -i -H "Origin: http://YOUR-SITE-URL" http://S3-or-CLOUDFRONT-URL | grep Access

在我的情况下,它在 S3 中可以正常工作,但在 CloudFront 中它只会有时返回访问控制标头:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000

经过更多研究,我发现我们的 CloudFront 分配配置为阻止标头进入 S3。要解决这个问题:

    在 AWS 控制面板中转到 CloudFront 分发 点击分发设置 单击“行为”选项卡 编辑默认模式行为 点击转发标头并选择白名单 添加 3 个建议的标头:Access-Control-Request-Headers、Access-Control-Request-Method、Origin 保存更改

一旦标头到达 S3,我们总是可以使用上面的 curl 命令看到正确的访问控制信息。

【讨论】:

这可能是 *** 上关于此主题的最完整答案,但它仍然不适合我。似乎 Cloudfront 仅来自我的子域(例如:www.myapp.com)的转发标头,但它不适用于我的域(myapp.com) - 如果有人知道为什么请看这里:***.com/questions/45528115/… 我必须将Access-Control-Allow-OriginAccess-Control-Allow-Methods 添加到标题中,但这种方法有效。基本上,您需要在飞行前请求中包含要发送的标头,以通过云端分发。很好的答案,谢谢! 另外仅供参考,该部分不再称为“Forward Headers”,现在是“Cache Based on Selected Request Headers”,然后选择“Whitelist” 这对我来说并不总是有效,我已经有这个问题好几个星期了,有时图像无法加载,我在控制台上看到 CORS 错误。重现这个错误并不容易。【参考方案2】:

我遇到了同样的问题,发现如下所示的暴露标题解决了这个问题:

<CORSConfiguration>
  <CORSRule>
    <AllowedOrigin>MYIP</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <ExposeHeader>ETag</ExposeHeader>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule>
</CORSConfiguration>

【讨论】:

MYIP 格式:对于我使用的本地开发机器:localhost:3000,因为它指定了请求触发的来源。 奇怪的是问题自发停止发生(在我实施此解决方案之前)。但如果它再次开始起作用,我会试试这个。 我又遇到了问题,实施您的解决方案,它似乎已经奏效。我将您的答案标记为正确。谢谢! 很快就谈到了。我再次收到错误。除了 ExposeHeader 之外,我还应该包含其他标签吗? 感谢 ETag 标头曝光对我有用。我在某处的文档中看到它,但无法再次找到它。我想在您的示例代码中指出您有两次“PUT”。也许应该是“GET”?

以上是关于从浏览器缓存提供图像时,AWS S3 + CloudFront 会出现 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS S3 上完全不设置缓存?

用于将 svg 图像上传到 AWS S3 的内容类型

从 heroku 访问 s3 内容时,AWS 访问密钥显示在浏览器 url 中

尝试从 S3 加载模型时,无法从链中的任何提供商加载 AWS 凭证 - 错误

当用户从托管在 Digital Ocean 上的 Web 应用程序将图像上传到 AWS S3 时,是出站还是入站带宽传输?

s3-amazon 图像 CORS 问题(仅在 5-8 小时后发生在少数浏览器中)