8

我希望浏览器始终添加(第一次除外)“If-Modified-Since”请求标头以避免不必要的流量。

响应头是:

Accept-Ranges:bytes
Cache-Control:max-age=0, must-revalidate
Connection:Keep-Alive
Content-Length:2683
Content-Type:text/html; charset=UTF-8
Date:Thu, 05 Apr 2012 13:06:19 GMT
Keep-Alive:timeout=15, max=497
Last-Modified:Thu, 05 Apr 2012 13:05:11 GMT
Server:Apache/2.2.21 (Red Hat)

FF 11 和 IE 9 都发送“If-Modified-Since”并得到 304 作为响应,但 Chrome 18 没有并得到 200。

为什么?如何强制 Chrome 发送“If-Modified-Since”标头?我不知道它是否重要,但所有请求都通过 HTTPS。

4

6 回答 6

27

我一直在追逐这个问题一段时间,以为我会分享我的发现。

“规则实际上很简单:证书的任何错误都意味着页面不会被缓存。”

https://code.google.com/p/chromium/issues/detail?id=110649

如果您使用的是自签名证书,即使您告诉 Chrome 为其添加例外以便页面加载,该页面的任何资源都不会被缓存,并且后续请求也不会具有 If-Modified-Since 标头。

于 2013-07-18T07:13:37.343 回答
6

我刚刚发现了这个问题,在对 Chrome 的If_Modified_Since行为感到困惑之后,我找到了答案。

Chrome 缓存文件的决定是基于Expires它接收到的标头。标Expires头有两个主要要求:

  1. 必须是格林威治标准时间 (GMT),并且
  2. 必须按照RFC 1123(基本上是RFC 822的四位数年份)进行格式化。

格式如下:

Expires: Sat, 07 Sep 2013 05:21:03 GMT

例如,在 PHP 中,以下输出格式正确的标头。

$duration = time() + 3600 // Expires in one hour.
header("Expires: " . gmdate("D, d M Y H:i:s", $duration) . " GMT");

(“GMT”被附加到字符串而不是“e”时区标志,因为当与 一起使用时gmdate(),该标志将输出“UTC”,RFC 1123 认为该标志无效。还要注意PHP 常量 DateTime::RFC1123DATE_RFC1123 不会提供正确的格式,因为它们以小时为单位将差异输出到 GMT [即 +02:00] 而不是“GMT”。)

有关详细信息,请参阅W3C 的日期/时间格式规范

简而言之,Chrome 只会在标题遵循这种确切格式的情况下才能识别它。这与Cache-Control标题相结合...

header("Cache-Control: private, must-revalidate, max-age=" . $duration);

...允许我实施适当的缓存控制。一旦 Chrome 识别出这些标头,它就会开始缓存我发送给它的页面(即使是查询字符串!),它也开始发送If_Modified_Since标头。我将它与存储的“最后修改”日期进行了比较,发回HTTP/1.1 304 Not Modified,一切正常。

希望这可以帮助其他绊倒的人!

于 2013-09-26T17:54:45.003 回答
5

我注意到几乎相同的行为,我的发现是:

  • 首先,chrome 中的 200 状态指示器并不是全部事实,您还需要查看“Size Content”列。如果这显示“(来自缓存)”,则资源直接从缓存中获取,甚至不询问它是否被修改。

  • 当请求具有 last-modified 标头的静态文件时,这种缺乏任何过期或 max-age 指示的资源缓存行为似乎适用。我注意到 chrome (ver. 22):

    1. 第一次请求文件(显然因为它不在缓存中)。
    2. 询问它是否被第二次修改(因为它在缓存中但没有新鲜的迹象)。
    3. 第三次直接使用,然后再使用(即使是新的浏览器会话)。
  • 我对这种行为有点困惑,但这是相当合理的,如果它是静态的,很久以前就被修改过,并且自上次检查以来没有改变,你可以假设它会在一段时间内有效(不知道他们是如何计算的)。

于 2012-11-05T13:40:26.837 回答
3

我遇到了同样的问题,在 Chrome 中所有请求总是状态码 200,在其他浏览器中是 304。

原来我在 Devtools - Settings - General 页面上签入了禁用缓存(在 DevTools 打开时) ..:)

于 2014-03-03T18:25:39.240 回答
2
  1. 不要在 Chrome 开发工具中禁用缓存(在“网络”选项卡上)。
  2. 缓存控制应该是Cache-Control: public. 用作PHP 函数true的第二个参数:headerheader("Cache-Control: public", true);
于 2017-11-13T17:12:30.283 回答
0

我还发现,如果我打开 DevTools,Chrome(最近的 v95+)也会返回缓存的 200 响应。它甚至从不将请求发送到服务器!如果我关闭 DevTools,行为应该是正常的,并且服务器会收到预期的请求。

于 2021-12-22T08:38:36.243 回答