【问题标题】:Why does Browser still sends request for cache-control public with max-age?为什么浏览器仍然使用 max-age 发送缓存控制公共请求?
【发布时间】:2013-09-04 14:53:08
【问题描述】:

我有 Amazon S3 对象,我为每个对象设置了

Cache-Control: public, max-age=3600000

大约是 41 天。

我将 Amazon CloudFront 分配设置为最小 TTL 也设置为 3600000。

这是清除缓存后的第一个请求。

GET /1.0.8/web-atoms.js HTTP/1.1
Host: d3bhjcyci8s9i2.cloudfront.net
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

响应是

HTTP/1.1 200 OK
Content-Type: application/x-javascript
Content-Length: 226802
Connection: keep-alive
Date: Wed, 28 Aug 2013 10:37:38 GMT
Cache-Control: public, max-age=3600000
Last-Modified: Wed, 28 Aug 2013 10:36:42 GMT
ETag: "124752e0d85461a16e76fbdef2e84fb9"
Accept-Ranges: bytes
Server: AmazonS3
Age: 342557
Via: 1.0 6eb330235ca3971f6142a5f789cbc988.cloudfront.net (CloudFront)
X-Cache: Hit from cloudfront
X-Amz-Cf-Id: 92Q2uDA4KizhPk4TludKpwP6Q6uEaKRV0ls9P_TIr11c8GQpTuSfhw==

即使 Amazon 明确发送了 Cache-Control,Chrome 仍然会发出第二个请求,而不是从 Cache 中读取。

GET /1.0.8/web-atoms.js HTTP/1.1
Host: d3bhjcyci8s9i2.cloudfront.net
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
If-None-Match: "124752e0d85461a16e76fbdef2e84fb9"
If-Modified-Since: Wed, 28 Aug 2013 10:36:42 GMT

问题: 为什么 chrome 会发出第二个请求?

过期 当我在标头中放置显式 Expires 属性时,此行为会发生变化。浏览器不会发送对 Expires 标头的后续请求,但对于公共缓存控制,它会发送它。我所有的 S3 对象永远不会改变,它们是不可变的,当我们更改文件时,我们将它们作为具有新 URL 的新对象。

在页面脚本参考中 Chrome 有时只会发出后续请求,我通过在浏览器中实际输入 URL 来进行此测试。当 HTML 页面引用脚本时,对于少数后续请求,chrome 会加载缓存的脚本,但有时会再次向服务器发送请求。这里不存在磁盘大小问题,Chrome 有足够的缓存空间。

问题是我们为每个请求付费,我希望 S3 对象被永久缓存,并且应该从缓存中加载并且永远不应该连接到服务器。

【问题讨论】:

    标签: google-chrome amazon-s3 http-headers amazon-cloudfront cache-control


    【解决方案1】:

    如果 HTTP 响应包含 etag 条目,则将始终发出条件请求。 ETag 是一个缓存验证器标签。客户端总是会发送 etag 到服务器,查看元素是否被修改。

    【讨论】:

    • 如果有 http 响应,则请求已经发生,max-age 被忽略。
    • 在我的测试中,Etag 没有发挥作用(我所有的资源都有一个 etag)。我很确定这就是您使用 Chrome 进行测试的方式。在地址栏上按“回车”是测试缓存的最佳方法。 F5 或单击重新加载并发送“max-age=0”标题。另见:stackoverflow.com/a/16510707/789658
    • 截至目前,Costa 的回复仍然相关:如果您刷新页面,Chrome 会在请求标头中发送 max-age=0。如果您在 URL 中按 Enter,则不会。
    • 在 Chrome 版本 57.0.2987.133(64 位)中,即使来自云端的响应有缓存控制:最大年龄=300。基本上,无论我如何发出请求,我似乎都无法从浏览器的缓存中获取它。我已经验证了开发工具中没有禁用浏览器缓存。有任何想法吗?这是一个图像。我想知道 Content-Type 是否与它有关。
    • 2 件事:1. 当直接在 Chrome 选项卡中转到 CloudFront 中我的图像的 URL 时,我可以让它可靠地从浏览器缓存中提取的唯一方法是通过后退/前进到 URL .如果我按 F5 或在 URL 中按 Enter,我总是会看到带有 304 的条件请求。 2. 仅在直接进入图像 URL 时才会出现这种情况。当在 HTML 文档的内容中使用时,缓存的工作方式如上所述,其中 F5 刷新并在 URL 中按 Enter 会产生不同的结果。只能假设 Chrome 将直接导航到 URL 视为它应该执行条件请求的标志。预期?
    【解决方案2】:

    如果 Chrome 开发者工具打开 (F12),Chrome 通常会禁用缓存。

    可在开发者工具设置中控制 - 开发工具顶部栏右侧的齿轮图标。

    【讨论】:

    • F12 仅在您勾选该框以禁用它时禁用缓存,当我测试缓存时我确定缓存已启用。
    • 很好的答案。我在服务器中进行了相关更改,并在打开开发工具 (F12) 的情况下检查结果,但看不到影响。有很多小事要知道。来自我的 +1。
    • 天啊!我没有意识到这一点!在我的浏览器中检查了开发人员工具“禁用缓存”-Doh!
    【解决方案3】:

    如果您点击刷新按钮以加载特定页面或资源,则每次都会发送 if-modified-since 标头请求,如果您改为在新选项卡中将页面/资源作为单独的请求或通过脚本或 html 页面,它将从浏览器缓存本身加载页面/资源。

    这就是我的情况,可能这是普遍的情况。我不完全确定,但这是我通过挖掘收集到的。

    【讨论】:

      【解决方案4】:

      当您在 Chrome 中按 F5 时,它会始终向服务器发送请求。这些将使用Cache-Control:max-age=0 标头制作。服务器通常会以 304(未更改)状态码进行响应。

      当您按下 Ctrl+F5Shift+F5 时,会执行相同的请求,但会使用Cache-Control:no-cache 标头,从而强制服务器发送未缓存的版本,通常带有 200(OK)状态码。

      如果您想确保使用本地浏览器缓存,只需在地址栏中按 Enter

      【讨论】:

      • 简单有效的答案。 TIL F5Enter 提出不同的请求。
      • 三天打我的头。谢谢!我正在按下 Ctrl + F5 并且不知道 Control:no-cache 来自哪里以及为什么浏览器忽略了我的 Cache-Control,或者我做错了什么。上帝,谢谢!和@GrasDouble,谢谢链接。我知道 cmets 不应该习惯于感谢,但找到你的答案是一种很大的解脱。
      • 很好的答案,我没有检查请求标头,您可以运行fetch 来检查它是否真的来自磁盘前:fetch('YOUR_URL')
      • 有什么方法可以避免在 F5 的情况下将请求发送到服务器?到目前为止,它将请求发送到服务器,然后服务器以 304 响应,然后从缓存中加载。我希望浏览器在有人按 F5 时直接从缓存中加载它,因为我的资源在磁盘缓存中可用。
      • @DebajitMajumder 然后你需要允许客户端这样做。通常带有Expires 标头。
      【解决方案5】:

      当您使用自签名证书时,Chrome 会添加 Cache-control: max-age=0 标头。从 HTTPS 切换到 HTTP 将删除此标头。

      Firefox 不添加此标头。

      【讨论】:

      • 我在使用 Chrome 在localhost 上测试响应缓存时遇到了一个非常相似的问题——尽管它不是发送max-age=0,而是发送nocache。当然,同样的结果。无论如何,很明显它 在每个请求中都发送这个,但不清楚为什么。这对于在本地开发服务器上测试缓存很有用,这几乎肯定会使用自签名证书。
      猜你喜欢
      • 2018-05-08
      • 2020-12-19
      • 2017-07-16
      • 2023-03-12
      • 2011-02-25
      • 2011-08-16
      • 2017-08-21
      • 2015-12-04
      • 1970-01-01
      相关资源
      最近更新 更多