我有一个包含很多小图像(图标)的页面。与 chrome 一起使用时,每次重新加载页面时,chrome 都会使用 if-modified-since 标头从服务器请求每个图标。
所有图标都带有 expires 和 max-age 标头。Firefox 从其缓存中加载图像。
为什么 chrome 会这样做,我该如何防止呢?
谢谢
我有一个包含很多小图像(图标)的页面。与 chrome 一起使用时,每次重新加载页面时,chrome 都会使用 if-modified-since 标头从服务器请求每个图标。
所有图标都带有 expires 和 max-age 标头。Firefox 从其缓存中加载图像。
为什么 chrome 会这样做,我该如何防止呢?
谢谢
你检查过请求头吗?
“'Cache-Control' 始终设置为 'max-age=0',无论您按 enter、f5 还是 ctrl+f5。除非您启动 Chrome 并输入 url 并按 enter。”
http://techblog.tilllate.com/2008/11/14/clientside-cache-control/
使用 chrome,无论您是刷新页面还是简单地访问它,都很重要。
当您刷新时,chrome 将为每个文件 ping 服务器,无论它们是否已被缓存。如果文件尚未修改,您应该会看到304 Not Modified响应。如果文件已被修改,您将看到200 OK响应。
不刷新时,缓存文件的状态为200 OK,但如果您查看网络面板的大小/内容列,您会看到(来自缓存)。
Expires
如果标头不是 RFC 的有效日期,Google Chrome 将忽略该标头。例如,它总是需要将天数指定为两位数。5 月 1 日应设置为“01 May”(而不是“1 May”),依此类推。Firefox 接受它们,这会误导用户认为问题出在浏览器(本例中为 Chrome)而不是标头值本身。
因此,如果您手动设置过期日期(不使用mod_expires
或类似的方法来计算实际日期),我建议您使用REDbot检查静态文件头。
对 Chrome 的检查器进行的快速实验表明,这只发生在页面重新加载时,而不是正常加载时。Chrome 只是试图刷新它的缓存。想一想——如果你设置Expires
了Max-Age
几十年,你是否要求浏览器缓存该资源并且从不检查它是否得到更新?它会尽可能缓存资源,但是当需要刷新页面时,它希望确保刷新整个页面。其他浏览器肯定也会这样做(尽管有些浏览器可以选择刷新前等待的小时数)。
感谢现代浏览器和服务器,刷新大量图标不会像你想象的那么慢——请求被流水线化以消除多次往返延迟,并且If-Modified-Since
标头的全部目的是允许服务器比较时间戳和返回“未修改”状态代码。这将发生在页面所需的每个资源上,但浏览器将能够一次发出所有请求并验证它们都没有改变。
也就是说,您可以做一些事情来使这更容易:
在 Chrome 的检查器中,使用资源选项卡查看它们是如何加载的。如果没有请求标头,则资源是直接从缓存中加载的。如果您看到304 Not Modified
,则资源已刷新但不需要再次下载。如果您看到200 OK
,则它已重新下载。
在 Chrome 的检查器中,使用审核选项卡查看它对资源可缓存性的看法,以防某些缓存标头不是最佳的。
所有这些If-Modified-Since
请求和 304 响应都可以加起来,即使它们只包含标头。将您的图像组合成精灵以减少请求的数量。
现代浏览器的缓存行为变得越来越复杂和智能。阅读http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements-in-internet-explorer-9.aspx了解一些示例和更多详细信息。
正如弗洛里安所说,不要与之抗争:-)
假设您正在运行 Apache,您可以尝试为文件系统中的某些文件类型和/或位置显式设置缓存生存期。
<FilesMatch ".(jpg|jpeg|png|gif)$">
Header set Cache-Control "max-age=604800, public" # 7 days
</FilesMatch>
或类似的东西
ExpiresByType image/jpeg "access plus 7 days"
ExpiresByType image/gif "access plus 7 days"
ExpiresByType image/png "access plus 7 days"
通常,我将通过在单个目录中使用来对文件类型进行分组,并相应地设置生命周期。
在这个年龄到期之前,浏览器根本不应该请求文件,但可能并不总是尊重它。您可能想要/需要使用 Last-Modified 和 ETag 标头。网上有很多关于这方面的好信息。
这听起来像是试图通过询问服务器自上次请求图像以来图像是否已更改来避免过时的缓存。听起来是件好事,而不是你想阻止的事情。