要点:
我有一个页面使用来自s3(HTML img
标记)的图片的标记加载,我有一个使用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标头的图像。
这个get的缓存和随后的CORS请求(一个在请求头中设置原点的请求)被拒绝,因为浏览器使用非CORS版本形成缓存。
解决这个问题的最佳方法是什么?我可以设置一些东西,以便非CORS版本永远不会被缓存吗?我应该通过将?some_flag
附加到请求的网址来区分CORS请求吗?
理想情况下,即使请求不包含“origin”,我也总是会发回所需的CORS标头。
答案 0 :(得分:9)
我遇到了同样的问题。正如@monsur所说,问题是S3没有设置“Vary:Origin”标题,即使它应该。不幸的是,据我所知,没有办法让S3发送该标头。但是,您可以通过在需要CORS时向请求(例如?origin=example.com
)添加查询字符串参数来解决此问题。查询字符串强制浏览器不使用缓存资源。
理想情况下,当启用CORS时,cloudfront和S3将发送Vary:Origin标头和/或Webkit会在Origin标头上隐式变化,我认为Firefox会这样做,因为它没有这个问题。
答案 1 :(得分:6)
它绝对不是最佳方式,但您可以通过向请求添加一些url参数来禁用图像请求的缓存。通常,这是通过javascript完成的,例如:
var img = document.createElement('img');
img.setAttribute('src', yourRequestUrl + '?d=' + Date.now());
tagToAppendImg.appendChild(img);
这将始终强制执行未缓存的响应,因为以毫秒为单位的日期始终会生成浏览器尚不知道的其他URL,但我不确定这是否可以解决您的问题。
答案 2 :(得分:2)
一种解决方案是在crossorigin='use-credentials'
- 标记上设置img
属性以强制浏览器始终执行CORS请求,请参阅此处:https://stackoverflow.com/a/34496683/725542
另一种解决方案是配置您的CloudFront分配以自动将非CORS请求转换为CORS请求。这可以通过使用最近添加的CloudFront功能“控制边缘到源请求标头”向CloudFront发送到S3的每个请求添加CORS标头。
此处的文档:http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html。
答案 3 :(得分:0)
您可以在提出CORS请求后使用Javascript附加img标记。
答案 4 :(得分:0)
我也遇到了这个问题。我最终在我的S3存储桶前设置了一个云端分发,并在cloudfront的Origin Custom Headers
部分设置了Origin Settings
选项,以便将Origin: https://example.com
发送到我的S3源。这会导致S3始终为CORS标头提供服务,因为它始终会看到Origin
请求标头。为此,您必须确保Origin
标头未被任何云端行为列入白名单。
tl; dr:我告诉cloudfront向我的S3源发送每个请求Origin: https://example.com
,并通过cloudfront提供我的内容。