使IE来caching资源,但总是重新validation

caching控制头“no-cache,must-revalidate,private”允许浏览器caching资源,但强制使用条件请求进行重新validation。 这在FF,Safari和Chrome中按预期工作。

但是,IE7 + 8不发送条件请求,即请求头中缺less“If-Modified-Since”,因此服务器使用HTTP / 200而不是HTTP / 304进行响应。

以下是完整的服务器响应头文件:

Last-Modified: Wed, 16 Feb 2011 13:52:26 GMT Content-type: text/html;charset=utf-8 Content-Length: 10835 Date: Wed, 16 Feb 2011 13:52:26 GMT Connection: keep-alive Cache-Control: no-cache, must-revalidate, private 

这看起来像一个IE错误,但我没有发现任何相关的networking上,所以我想知道是否缺席或存在的另一个头使IE的行为奇怪?

关于no-cache和max-age之间差别的一个很好的讨论: Cache-Control:max-age = 0和no-cache之间有什么区别?

我终于明白了。 这里是一个解释和testing的解决scheme。

以下网站确认我的观察: http : //blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/

它说IE不会在本地存储带有“no-cache”指令的页面,因此总是发送一个无条件的请求。

还有一个MS支持文章 – https://support.microsoft.com/help/234067/ – 确认这一点:

“Internet Explorer支持HTTP 1.1caching控制标头,当指定no-cache值时,它阻止所有caching特定Web资源…”

这种行为并不完全错误 – 但这不是RFC 2616(第14.9.1节)的意图。 关于'no-cache'它说:“一个caching不能使用响应来满足后续的请求,如果没有与源服务器成功的重新validation。 所以响应可以被caching,但必须重新validation它。 主要的浏览器,除了IE浏览器,caching响应并重新validation它。 为了防止存储请求,有“无存储”caching控制指令。

总之,IE将“无caching”视为“无存储”。

以下是以一致的方式为IE和其他浏览器启用条件请求解决scheme

不要使用no-cache,而是将Expires标头设置为过去(或-1,具有相同的效果)。 IE以及其他主要浏览器将发送条件请求。 (注意,你也应该知道IE Vary头部错误,这可以防止caching。)

这些是关键的标题字段:

 Last-Modified: Wed, 16 Feb 2011 13:52:26 GMT Expires: -1 Cache-Control: must-revalidate, private 
  • 需要Last-Modified(或者ETag)作为validation器
  • 过期-1表示资源已过时,必须重新validation
  • Cache-Control不能包含no-cache或no-store
  $last_modified = filemtime($_SERVER['SCRIPT_FILENAME']); session_cache_limiter(FALSE); header("Content-Type: text/css"); header("Cache-Control: max-age=1, must-revalidate, private"); header("Last-Modified: " . gmdate("D, d MYH:i:s", $last_modified) . " GMT"); if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) { if(strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) >= $last_modified) { header("HTTP/1.1 304 Not Modified"); exit; } }