【问题标题】:Cached non CORS response conflicts with new CORS request缓存的非 CORS 响应与新的 CORS 请求冲突
【发布时间】:2012-09-11 23:56:38
【问题描述】:

要点:

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

详情:

edit:在 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 附加到请求的 url 来区分 CORS 请求吗?

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

【问题讨论】:

  • 你用的是什么浏览器?这种行为是否在所有浏览器中都会出现?这听起来像一个浏览器错误。您提出的查询参数解决方案听起来不错。
  • 添加了“编辑:在 safari 5.1.6 和 chrome 21.0.1180.89 中都失败。在 Firefox 14 中运行良好。”
  • 那么可能是一个 WebKit 错误。这听起来像是同一个问题:bugs.webkit.org/show_bug.cgi?id=63090 该错误建议添加标题“Vary: Origin”可能会解决问题。
  • 这个问题也已经在AWS S3 Forums上报告了

标签: caching amazon-s3 xmlhttprequest cors


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      一种解决方案是在 img-tag 上设置 crossorigin='use-credentials' 属性以强制浏览器始终执行 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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-24
            • 2015-11-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多