由于 CORS,无法从 S3 存储桶中获取图像
Posted
技术标签:
【中文标题】由于 CORS,无法从 S3 存储桶中获取图像【英文标题】:Fetching an image from S3 bucket is not working because of CORS 【发布时间】:2019-11-29 20:47:36 【问题描述】:问题是当我尝试使用fetch
API 获取时,我收到了 cors 错误(响应标头不包含 Access-Control-Allow-Origin
)。这是我在 S3 中的 cors 配置 -
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
代码可以在这里找到 - https://codepen.io/sourov0805045/pen/OKVBXM?editors=1111
我检查了响应标头,发现它不包含 Allow-Access-Control-Origin
标头。
但是如果我将它添加到 <img>
标记中,这会正常工作,这非常令人费解。那时响应标头中也没有Access-Control-Allow-Origin
,但图像加载正常。
A 已尝试与axios
相同,但没有效果。
请告诉我您对如何解决此问题的建议。
【问题讨论】:
如果您在同源上下文中请求对象,然后在跨源上下文中请求对象,则 S3 上的 CORS 会损坏,因为 S3 不会在非 CORS 响应上添加Vary: Origin
响应标头。我在serverfault.com/a/856948/153161 解决了这个缺陷,其中包括对 CloudFront 的引用,但无论是否使用 CloudFront,S3 都是问题的根源。
嗨@Michael-sqlbot 我认为我的问题更基本。如果你看到 codepen,你会看到我只是发出一个 fetch 请求,所以它并没有真正使用缓存。此外,该问题在 Firefox 中也可以重现。
你已经解决了吗?我现在在您的 codepen 编辑器中单击按钮时得到正确的响应标头:Accept-Ranges: bytes Access-Control-Allow-Methods: GET, POST, PUT, HEAD, DELETE Access-Control-Allow-Origin: * Content -长度:1573767 内容类型:应用程序/八位字节流日期:格林威治标准时间 2019 年 7 月 24 日星期三 19:41:17 ETag:“8e26c03714ab4d8e185c29b1c04639f0” 最后修改时间:2019 年 6 月 26 日星期三 19:18:40 GMT 服务器:AmazonS3 变化:来源,访问控制请求标头,访问控制请求方法 x-amz-id-2:[...] x-amz-request-id:[...]
是的,已经解决了,稍后会更新问题。
@RasheduzzamanSourov 你有没有机会提供你承诺的更新:D?
【参考方案1】:
首先删除不必要的变量:从命令行使用 cURL。
第 1 步:发出飞行前OPTIONS
请求:
curl -H "Origin: http://example.com" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X OPTIONS --verbose \
'https://twisker-s3-files.s3.us-east-2.amazonaws.com/files/-GxfyX_dZ-6313383.jpg'
您在输出中寻找的响应标头是:
...
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, PUT, HEAD, DELETE
< Access-Control-Allow-Headers: x-requested-with
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
...
第 2 步:发出 GET
请求:
~ $ curl --head 'https://twisker-s3-files.s3.us-east-2.amazonaws.com/files/-GxfyX_dZ-6313383.jpg' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/75.0.3770.142 Safari/537.36' -H 'Referer: https://cdpn.io/boomboom/v2/index.html?editors=1111&key=iFrameKey-a88ea9ee-51a6-0ae2-7350-951a5b1e4e56' -H 'Origin: https://cdpn.io' --compressed
回复如下:
HTTP/1.1 200 OK
x-amz-id-2: 9D3J5BnHo7YocXQicso+eQAC/PlyoOMpc5QXd+G77HMtWTOd8kYymcJnQ0T8J7tqXetMZgVO8Rw=
x-amz-request-id: 6CE1579D5B039163
Date: Thu, 25 Jul 2019 02:18:41 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, HEAD, DELETE
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Last-Modified: Wed, 26 Jun 2019 19:18:40 GMT
ETag: "8e26c03714ab4d8e185c29b1c04639f0"
Accept-Ranges: bytes
Content-Type: application/octet-stream
Content-Length: 1573767
Server: AmazonS3
注意事项:
Access-Control-Allow-Origin
和 Access-Control-Allow-Methods
存在
它们的值看起来是正确的,所以 CORS 应该对你有用(它在你的 URL 上对我有用)
https://www.test-cors.org 可用于测试 CORS 请求。它在请求的每个阶段都给出了一些输出。
最后,浏览器在缓存 pre-flight OPTIONS 请求方面非常积极。因此,如果您正在查看 chrome 网络调试工具,您可能看不到 pre-flight OPTIONS 请求。有时重新启动 chrome 会清除 OPTIONS 缓存,有时需要清除所有浏览器缓存。
如果您没有正确配置服务器端的 CORS,并且浏览器缓存响应,则此缓存可能会出现问题。例如:最初配置 CORS 时不允许使用 GET
。您发出OPTIONS
请求,浏览器缓存响应,阻止未来的GET
请求。
【讨论】:
感谢您的回答,不明白为什么我无法加载设置 CORS 以允许 AWS 中的所有来源的 svg【参考方案2】:由于 S3 链接以 //
开头,它将使用当前协议发出请求。如果您有http://localhost
,即使AllowedOrigins
是*
,AWS 也不允许您通过http 发出请求。
在 axios url 参数中使用 https
前缀 URL,它应该可以工作。
【讨论】:
以上是关于由于 CORS,无法从 S3 存储桶中获取图像的主要内容,如果未能解决你的问题,请参考以下文章
如何从 s3 存储桶中获取 Pyspark 中带有前缀的文件?
如何获取 Rails 应用程序的 CORS 标头以访问 aws s3 存储桶?