Chrome不会发送“If-Modified-Since”

时间:2012-04-06 07:48:40

标签: 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)

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

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

5 个答案:

答案 0 :(得分:21)

我一直在追逐这个问题一段时间,以为我会分享我找到的东西。

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

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

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

答案 1 :(得分:4)

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

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

  • 在请求具有最后修改标头的静态文件时,缺少任何expires或max-age指示的资源的缓存行为似乎适用。我注意到了chrome(第22版):

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

答案 2 :(得分:4)

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

Chrome决定缓存文件的依据是它收到的Expires标头。 Expires标题有两个主要要求:

  1. 必须处于格林威治标准时间(GMT)和
  2. 必须根据RFC 1123格式化(基本上RFC 822,年份为四位数。)
  3. 格式如下:

    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认为该标志无效。另请注意{ {3}} DateTime::RFC1123DATE_RFC1123 不会提供正确的格式,因为它们会在几小时内将差异输出到GMT [即+02: 00而不是“GMT”。)

    有关详细信息,请参阅PHP constants

    简而言之,只有符合此格式的Chrome才能识别标题。这与Cache-Control标题相结合......

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

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

    希望这有助于其他任何偶然发现的人!

答案 3 :(得分:2)

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

事实证明我在Devtools - 设置 - 常规页面上检查了禁用缓存(当DevTools打开时)。:)

答案 4 :(得分:1)

  1. 请勿在Chrome开发者工具中禁用缓存(在“网络”标签页上)。
  2. 缓存控制应为Cache-Control: public。使用true作为header PHP函数的第二个参数:header("Cache-Control: public", true);