S3 CORS,总是发送Vary:Origin

Tha*_*yne 16 amazon-s3 cors amazon-cloudfront

我正在使用支持CORS的Cloudfront背后的S3存储桶.如果客户端使用Origin标头发出请求,则S3(和cloudfront)使用"Vary:Origin"标头进行响应,但是如果请求是在没有Origin标头的情况下生成的,则响应不包含任何Vary标头.

这是有问题的,因为我在img标签中使用来自cloudfront/s3的资源,在这种情况下,浏览器发出没有Origin标头的请求,然后稍后对所述图像发出ajax请求.然后,浏览器使用图像的缓存版本,而不使用Access-Control-Allow-Origin标头,因此拒绝该请求.

有没有办法让S3始终返回"Vary:Origin"标题?

小智 20

我刚刚回答了你的问题,因为这类问题(以及一些相关问题)的答案很少.

你描述的问题出于某种原因主要是在chrome,FF和IE似乎足够聪明,不能在这些实例中的AJAX和常规调用之间共享缓存.

问题

让我们首先描述为什么问题会在未来的读者中发生:

  • 浏览器(Chrome)使用常规<img><script>标记询问服务器.如果服务器位于同一域中,则不包含CORS头.
  • 服务器(S3)返回资源.如果请求中没有Origin头,则它不会在回复中附加CORS头,因为它们是冗余的.
  • 浏览器(Chrome)尝试使用AJAX再次获取资源,但这次并没有真正进入服务器,而是查看缓存的资源.
  • 浏览器(Chrome)缓存版本没有CORS标头.它会将请求作为Access-Control-Allow-Origin违规或其他相关问题丢弃.

解决方案

在HTML5中,有一个名为的属性crossorigin可以添加到标签中,表示他们需要发送原始信息.可能的值是crossorigin='anonymous',crossorigin='use-credentials'这些与提出的问题完全无关,但正如文档中所述:

默认情况下(即,未指定属性时),根本不使用CORS.

https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes

所以只需创建这样的图像标签即可 <img src='cloundfront.path' crossorigin='use-credentials'>

而已.它非常模糊,所以我希望这个答案可以为一群人节省一些研究时间.

  • 我假设 `crossorigin="use-credentials"` 等同于在 XHR 请求上调用 `withCredentials` 是否正确?如果是这样,只要确保返回 CORS 标头,`crossorigin="anonymous"` 是否也能正常工作?如果可以的话,我宁愿不允许我的静态图像做设置 cookie 之类的事情。 (2认同)

Kri*_*amp 11

另一种解决方案是配置CloudFront分配以自动将非CORS请求转换为CORS请求.这可以通过向CloudFront使用最近添加的CloudFront功能"Control Edge-To-Origin Request Headers"发送到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.

  • 很好,这将强制 Access-Control-Allow-Origin,但是对于 Vary: Origin 呢? (2认同)
  • 但是,如果您强制CloudFront始终向S3发送"Origin:X.domain.com",则CloudFront无法返回"Access-Control-Allow-Origin:Y.domain.com".换句话说,此强制标头解决方案仅在您返回"Access-Control-Allow-Origin:*"通配符响应标头或仅在我们的"Access-Control-Allow-Origin"标头中返回_single_域时才有效. (2认同)