我希望浏览器始终添加(除了第一次)“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。
答案 0 :(得分:21)
我一直在追逐这个问题一段时间,以为我会分享我找到的东西。
“规则实际上很简单:证书的任何错误都意味着页面不会被缓存。”
https://code.google.com/p/chromium/issues/detail?id=110649
如果您使用的是自签名证书,即使您告诉Chrome为其添加例外以便加载该页面,也不会缓存该页面中的资源,并且后续请求将不会具有If-Modified-自标题。
答案 1 :(得分:4)
我注意到了几乎相同的行为,我的发现是:
首先,chrome中的200状态指示器并非全部,您还需要查看“大小内容”列。如果这表示“(来自缓存)”资源直接从缓存中获取,甚至没有询问它是否被修改。
在请求具有最后修改标头的静态文件时,缺少任何expires或max-age指示的资源的缓存行为似乎适用。我注意到了chrome(第22版):
我对这种行为感到有些困惑,但它是相当合理的,如果它是静态的,很久以前就被修改了,并且自从上次检查以来没有改变你可以认为它会是有效期一段时间(不知道他们如何计算)。
答案 2 :(得分:4)
我刚刚发现了这个问题,在对Chrome的If_Modified_Since
行为感到困惑之后,我找到了答案。
Chrome决定缓存文件的依据是它收到的Expires
标头。 Expires
标题有两个主要要求:
格式如下:
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::RFC1123
和DATE_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)
Cache-Control: public
。使用true
作为header
PHP函数的第二个参数:header("Cache-Control: public", true);