【问题标题】:Chrome + CORS + cache - requesting same file from two different originsChrome + CORS + 缓存 - 从两个不同的来源请求相同的文件
【发布时间】:2014-12-08 17:33:51
【问题描述】:

我在使用 Chrome 时遇到了一个我似乎无法完全理解的问题,我很好奇这里的人们以前是否处理过它。这不会在 Firefox 中重现。步骤如下:

  1. 启动隐身 Chrome,导航到 https://foo.mysite.com 并让页面上的 JS 向 S3 发出 GET ajax 请求以获取 https://s3.amazonaws.com/mystuff/file.json 。您会收到 200 响应:

    HTTP/1.1 200 OK
    x-amz-id-2: somestuffhere
    x-amz-request-id: somestuffhere
    Date: Tue, 14 Oct 2014 03:06:41 GMT
    Access-Control-Allow-Origin: https://foo.mysite.com
    Access-Control-Allow-Methods: GET
    Access-Control-Max-Age: 3000
    Access-Control-Allow-Credentials: true
    Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
    Cache-Control: max-age=86400
    Content-Encoding: gzip
    Last-Modified: Sun, 05 Oct 2014 00:29:53 GMT
    ETag: "fe76607baa40a793eb3b3cbd373a3fb8"
    Accept-Ranges: bytes
    Content-Type: application/json
    Content-Length: 5609
    Server: AmazonS3
    
  2. 打开第二个选项卡,导航到 https://bar.mysite.com 并让其 JS 向 S3 发出 GET ajax 请求以获取同一文件 https://s3.amazonaws.com/mystuff/file.json 。取回以下 304 响应:

    HTTP/1.1 304 Not Modified
    x-amz-id-2: somestuffhere
    x-amz-request-id: somestuffhere
    Date: Tue, 14 Oct 2014 03:06:58 GMT
    Access-Control-Allow-Origin: https://bar.mysite.com
    Access-Control-Allow-Methods: GET
    Access-Control-Max-Age: 3000
    Access-Control-Allow-Credentials: true
    Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
    Cache-Control: max-age=86400
    Last-Modified: Sun, 05 Oct 2014 00:29:53 GMT
    ETag: "fe76607baa40a793eb3b3cbd373a3fb8"
    Server: AmazonS3
    
  3. 打开第三个选项卡,导航到https://foo.mysite.com(第一个站点)并重复与 1 中相同的步骤。Chrome 因 CORS 原因终止响应并报告以下内容:

    XMLHttpRequest cannot load https://s3.amazonaws.com/mystuff/file.json. The 'Access-Control-Allow-Origin' header has a value 'https://bar.mysite.com' that is not equal to the supplied origin. Origin 'https://foo.mysite.com' is therefore not allowed access.
    

这里有什么故事?这不会在 Firefox 中重现。在 Firefox 中,我很高兴在第 2 步和第 3 步中都得到了 304,我希望在 Chrome 中也能看到。

在 Chrome 中解决此问题的一个临时解决方法是在 S3 中的文件上设置 Cache-Control: no-cache,但随后我会强制我们的客户重新下载该文件没有充分的理由,所以这不是一个真正的解决方案。

这是预期的并记录在案的行为吗?这是 Chrome 的错误吗?还有其他想法吗?

【问题讨论】:

  • 这听起来像是代理缓存问题,只是在响应中设置了Vary 标头,这应该可以防止代理缓存问题。您可以检查并共享响应 #3(失败响应)的响应标头吗?
  • 从未收到来自服务器的请求,因为 Chrome 取消了该请求。它显示了临时请求标头和最佳标头,这些都不是很有帮助。我试图看看是否可能通过 chrome://net-internals 捕获会导致看到响应,但它也永远不会超过那里的请求。
  • s/request/response/ 在上面的第一句话中。
  • 无法在 Chromium 38.0.2125.106 中重现(使用 netcat)。你能提供一个演示页面和网站吗?

标签: google-chrome amazon-s3 cross-domain cors chromium


【解决方案1】:

我发现这个博客有帮助:Add Vary headers to S3 它通过向所有 XHR 请求添加 Vary 标头来提供帮助。

我确实遇到了 html 请求(即 )的问题,但我能够通过使用此处描述的 hackround#2 来克服这个问题:https://serverfault.com/a/856948

hack#2 的

TL;DR 是使用“虚拟”查询字符串参数,该参数对于 HTML 和 XHR 不同,或者其中一个不存在。例子: <img src="https://s3.png?x-request=html">

【讨论】:

    【解决方案2】:

    看起来这是由Chromium issue 260239引起的

    【讨论】:

    • 有趣。我想知道为什么第二个请求成功。由于第一个响应被缓存,它不应该失败吗?
    • 目前还不清楚为什么这只发生在第三次请求时。
    • 这也发生在我们 FF 身上。我认为这可能与缺少 Vary 标头有关。
    • 这个错误在 chrome 79 中仍然存在
    【解决方案3】:

    我只是在请求 URL 中添加一个时间戳来强制再次从 S3 加载资产,而不是从缓存中加载,例如 xxxx?timestamp=yyyy

    【讨论】:

    • 如果请求 url 是 https://{bucket-name}.s3.amazonaws.com/ 并用作表单操作,这也可以吗?
    猜你喜欢
    • 2015-12-26
    • 2020-01-25
    • 2013-11-19
    • 2017-06-27
    • 2021-08-22
    • 1970-01-01
    • 2016-03-04
    • 2018-08-30
    • 1970-01-01
    相关资源
    最近更新 更多