Chrome不会发送"If-Modified-Since"

Gar*_*yIV 6 http if-modified-since

我希望浏览器始终添加(除了第一次)"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)
Run Code Online (Sandbox Code Playgroud)

FF 11和IE 9都发送"If-Modified-Since"并得到304响应,但Chrome 18没有得到200.

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

Nee*_*eek 21

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

"规则实际上非常简单:证书的任何错误都意味着页面不会被缓存."

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

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


the*_*ion 6

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

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

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

格式如下:

Expires: Sat, 07 Sep 2013 05:21:03 GMT
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

简而言之,Chrome 只会识别符合此确切格式的标头。这,结合Cache-Control标题......

header("Cache-Control: private, must-revalidate, max-age=" . $duration);
Run Code Online (Sandbox Code Playgroud)

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

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

  • 谢谢,GMT 时区是我的问题,我没有注意到:) (2认同)

小智 5

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

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

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

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