您在响应标头中缺少某种缓存验证。ETag
标头可用于控制它,方法是向其添加可识别唯一响应的值。您可以在Apache ETag 文档中阅读一些有关它的信息,但我会ETag: [filename]
在您的示例中简单地包含在您的响应标头中:
Accept-Ranges:bytes
Cache-Control:max-age=276
Connection:keep-alive
Content-Encoding:gzip
Content-Length:3310
Content-Type:text/html; charset=UTF-8
Date:Tue, 12 Mar 2013 09:24:12 GMT
Expires:Tue, 12 Mar 2013 09:28:48 GMT
Server:Apache
ETag: File:"somefile.html"
Vary:Accept-Encoding
这些ETag
值可以包括几乎任何东西,例如文件名、文件大小、自定义值……可以用分号分隔;
。如果值包含空格,则将它们括在双引号中"
。例如:
ETag: File:"YouTube_cd_Fdly3rX8.jpg"; Size:12169
连同Cache-Control
,Expires
和其他一些可能改变的头值(当被包含并且浏览器知道如何解释它们时)将构成浏览器缓存验证器的基础。
查看您的示例响应标头,您可能希望将max-age值Cache-Control
增加到更高的值,因为您的示例表明它们应该仅在客户端缓存 276 秒。标Expires
头值似乎也有点短。
有关如何设置这些值以及浏览器如何验证缓存控制标头的更多信息,请参阅RFC2616 第 14.9 节。
编辑:在进一步调试、检查和重新检查 Chrome 缓存验证的行为后,事实证明它确实不尊重正确设置的Cache-Control
响应标头。应 OP 的要求,我已将此问题报告给 Chrome 支持:
铬,版本 25.0.1364.172 m
从 Web 服务器提供静态文件时,不尊重主文档请求上的 Cache-Control,同时尊重链接内容的相同标头响应。
测试设置:
从 Web 服务器请求静态 HTML 文档(MIME 文本/html),其中包含另一个带有 IFRAME 的静态 HTML 文档(也是 MIME 文本/html)。IFRAME 提供的文档具有与主文档相同的响应标头,由 Web 服务器响应附加到它:
Date: Thu, 21 Mar 2013 16:29:28 GMT
Expires: Thu, 21 Mar 2013 16:33:59 GMT
Cache-Control: max-age=301, max-stale=299, only-if-cached
预期行为:
主文档和在 IFRAME 中提供的文档将在本地缓存,初始请求的持续时间至少为 301(max-age)秒,对于正常(非强制)加载请求,额外的 299(max-stale)秒。在这个 301 秒的时间范围内的任何后续请求不会使本地缓存失效(例如使用 CTRL+F5 强制刷新或重新加载上下文菜单命令)并且由正常的页面加载请求(例如重新进入地址栏中的相关 URL)将从本地缓存加载状态消息 200 OK(来自缓存),如果没有本地缓存控制信息指示它,否则(相同的 URL,在有效的缓存时间范围内请求,文档是标记为正确缓存在其响应标头中)。
问题:
主文档未通过其缓存副本加载,并且向 Web 服务器发出附加请求,导致状态代码 304 Not Modified。然而,IFRAME 中的文档是从本地缓存正确加载的,并导致状态消息 200 OK(来自缓存)。
笔记:
没有任何缓存控制标记或其值的任何组合似乎对主文档的本地缓存行为有任何积极影响。包含一个非唯一的 ETag 值也不能解决缓存主文档的问题。其他主要供应商浏览器(在 IE、Firefox、Opera 中测试)尊重主文档上的 Cache-Control 标头。