34

要旨:

我有一个页面使用标签加载来自 s3(HTMLimg标签)的图像,我有一个使用xmlhttprequest. 标签加载在没有 CORS 标头的情况下被缓存,因此xmlhttprequest看到缓存的版本,检查它的标头并因跨源错误而失败。

细节:

编辑:在 safari 5.1.6 和 chrome 21.0.1180.89 中都失败。在 Firefox 14 中运行良好。

使用 S3 的新 CORS,我CORSRule这样设置:

<CORSRule>
  <AllowedOrigin>*</AllowedOrigin>
  <AllowedMethod>GET</AllowedMethod>
  <AllowedMethod>HEAD</AllowedMethod>
  <MaxAgeSeconds>0</MaxAgeSeconds>
  <AllowedHeader>*</AllowedHeader>
</CORSRule>

如果我从 S3 请求图像而没有在请求标头中设置来源,我会在响应中返回没有任何 CORS 标头的图像。

由于浏览器使用缓存中的非 CORS 版本,此获取的缓存和后续 CORS 请求(确实在请求标头中设置来源的请求)被拒绝。

解决这个问题的最佳方法是什么?我可以设置一些东西,使非 CORS 版本永远不会被缓存吗??some_flag我应该通过将 a 附加到请求的 url 来区分 CORS 请求吗?

理想情况下,即使请求不包含“来源”,我也会让 S3 始终发回所需的 CORS 标头。

4

5 回答 5

9

我遇到了同样的问题。正如@monsur 所说,问题在于 S3 没有设置“Vary: Origin”标题,即使它应该设置。不幸的是,据我所知,没有办法让 S3 发送该标头。但是,您可以通过在请求中添加查询字符串参数来解决此问题,例如?origin=example.com当您需要 CORS 时。查询字符串强制浏览器不使用缓存的资源。

理想情况下,cloudfront 和 S3 会在启用 CORS 时发送 Vary:Origin 标头和/或 Webkit 会隐式地改变 Origin 标头,我假设 Firefox 会这样做,因为它没有这个问题。

于 2014-03-21T00:48:51.547 回答
6

这绝对不是最好的方法,但您可以通过向请求添加一些 url 参数来禁用图像请求的缓存。通常,这是通过 javascript 完成的,例如:

var img = document.createElement('img');
img.setAttribute('src', yourRequestUrl + '?d=' + Date.now());
tagToAppendImg.appendChild(img);

这将始终强制执行未缓存的响应,因为以毫秒为单位的日期总是会产生浏览器尚不知道的不同 URL,但我不确定这是否能解决您的问题。

于 2014-04-01T11:17:33.993 回答
3

一种解决方案是crossorigin='use-credentials'在 -tag 上设置属性img以强制浏览器始终执行 CORS 请求,请参见此处:https ://stackoverflow.com/a/34496683/725542

另一种解决方案是将您的 CloudFront 分配配置为自动将非 CORS 请求转换为 CORS 请求。这可以通过使用最近添加的 CloudFront 功能“控制边缘到源请求标头”向 CloudFront 发送到 S3 的每个请求添加 CORS 标头来实现。

在此处查看功能公告:https ://aws.amazon.com/blogs/aws/cloudfront-update-https-tls-v1-1v1-2-to-the-origin-addmodify-headers/

以及此处的文档:http: //docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html

于 2016-01-14T10:08:26.503 回答
2

我也遇到了这个问题。我最终在我的 S3 存储桶前设置了一个云端分发,并在云端部分中设置Origin Custom Headers选项Origin Settings以发送Origin: https://example.com到我的 S3 源。这会导致 S3 始终为 CORS 标头提供服务,因为它始终会看到Origin请求标头。为此,您必须确保Origin您的任何云端行为都没有将标头列入白名单。

tl;dr:我告诉 cloudfront 将Origin: https://example.com每个请求发送到我的 S3 源,并通过 cloudfront 提供我的内容。

于 2016-04-22T17:47:40.103 回答
0

在发出 CORS 请求后,您可以使用 Javascript 附加 img 标签。

于 2014-05-28T20:26:35.510 回答