从浏览器缓存提供图像时,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-Origin
和Access-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 错误的主要内容,如果未能解决你的问题,请参考以下文章
从 heroku 访问 s3 内容时,AWS 访问密钥显示在浏览器 url 中
尝试从 S3 加载模型时,无法从链中的任何提供商加载 AWS 凭证 - 错误
当用户从托管在 Digital Ocean 上的 Web 应用程序将图像上传到 AWS S3 时,是出站还是入站带宽传输?