如何使用控制缓存标头?

Posted

技术标签:

【中文标题】如何使用控制缓存标头?【英文标题】:how to use control-cache headers? 【发布时间】:2011-02-05 09:15:52 【问题描述】:

我为 Google chrome 下载了 Google 速度跟踪器,以查看我的网站在性能方面的表现如何,它告诉我需要为某些文件启用缓存,例如我的 style.css、图像等。

我读过下面的 php 代码应该告诉浏览器缓存 html 内容。我写了一个快速的 php 页面,上面有几张图片,并将下面的代码贴在顶部(在发送标题之前)以测试它是如何工作的。

Header("Cache-Control: public, max-age=3600, must-revalidate");

当我回到速度追踪器的分析时,它说...

总结 来自缓存:false

请求标头 Pragma:没有缓存 缓存控制:max-age=0

但在响应标头下... Cache-Control: public, max-age=3600, must-revalidate (正是我指定的)

我有点困惑,这是怎么回事……?当它说 from cache: false 是否意味着来自服务器缓存而不是客户端缓存?

【问题讨论】:

请告诉我你的发现 【参考方案1】:

关键是must-revalidate:这意味着客户端询问服务器文件是否已更改。如果您不处理这种情况,浏览器将获取一个新副本。

阅读Mark Nottingham’s fantastic Caching Tutorial 了解更多信息。 作为 PHP 实现的示例,您可以使用 my code。

查看 $_SERVER['HTTP_IF_NONE_MATCH']$_SERVER['HTTP_IF_MODIFIED_SINCE'] 以验证客户端。请注意,这两个标头都可能包含恶意代码。 ;)

【讨论】:

所以你的意思是,可以缓存“图像、CSS、脚本等”。使用这种方法无需修改服务器配置? 是的,静态文件由服务器处理。可执行文件(PHP、SSI、CGI)必须自己执行此操作,因为服务器无法知道它们产生了什么内容。 这个答案是错误的 - 如果正确实施,提供的标头将强制缓存内容。 当您说“如果实施得当...”时,您愿意详细说明吗?谢谢 10 倍。 在别处查看我的答案 - 我没有完全研究您的问题以查看 header() 调用是否正常工作。【参考方案2】:

当它说 from cache: false 时 这意味着来自服务器缓存和 不是客户端的缓存?

^ 这是指客户端缓存。

以这种方式设置缓存将覆盖您的 PHP 文件,但您需要在服务器端实现其他东西来缓存您的图像、CSS、脚本等。如果您的服务器支持,这可以使用 .htaccess 完成它。

例如,这是我在几个网站的 .htaccess 文件中使用的。

<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)(\.gz)?$">
  Header set Expires "Thu, 15 Apr 2012 20:00:00 GMT"
  Header unset ETag
  FileETag None
</FilesMatch>

【讨论】:

我希望就像将 .htaccess 文件粘贴到我的站点目录中一样简单。我们公司租用 IIS6 服务器(不使用 .htaccess 文件),我没有直接控制权通过 ftp 以外的服务器进入站点目录... @payling:IIS 可能有自己的配置处理程序来做同样的事情,但如果一切都失败了,您可以使用 PHP 文件以&lt;?php headers("..."); echo file_get_contents("yourfile.css"); ?&gt; 的方式为您的 css/etc 提供服务.不过,你真的应该只在必要时才这样做。【参考方案3】:

我不熟悉这个工具,但是在任何浏览器获取带有缓存标头的内容之前,它都无法缓存它。您的服务器似乎正在发回预期的标头,并且该页面应该由浏览器缓存 - 您的浏览器应该现在在其缓存中有一个副本。如果您再次尝试获取相同的页面,那么它将从缓存而不是源服务器中获取(假设 1 小时的时间限制尚未到期)。

请注意,某些浏览器会将刷新请求解释为显式请求以忽略缓存并再次获取页面 - 尝试通过链接访问它,而不是点击刷新按钮。

C.

【讨论】:

据我所知,我发布的代码对我没有任何作用。我使用提琴手来分析流量,无论浏览器是否从缓存的图像/样式表中绘制代码。这让我很困惑,因为 Speed Tracer 的说法正好相反……我将花更多时间了解发生了什么。【参考方案4】:

您需要了解这些 Cache-Control header field 指令的实际含义:

public

表示响应可以被任何缓存缓存,即使它通常是不可缓存的或只能在非共享缓存中缓存。 (有关更多详细信息,另请参阅Authorization, section 14.8。)

max-age=3600 指定响应是新鲜的 3600 秒:

当缓存响应中存在 max-age cache-control 指令时,如果响应的当前年龄大于对该资源的新请求时给定的年龄值(以秒为单位),则该响应是陈旧的。响应上的 max-age 指令意味着响应是可缓存的(即“公共”),除非还存在其他一些限制性更强的缓存指令。

must-revalidate 指定缓存必须在缓存响应过时后重新验证缓存响应,然后才能使用缓存响应来满足请求:

当缓存接收到的响应中存在 must-revalidate 指令时,该缓存不能在该条目变得陈旧后使用该条目来响应后续请求,而无需先向源服务器重新验证它。 (即,如果仅基于原始服务器的 Expires 或 max-age 值,缓存的响应已过时,则缓存必须每次都进行端到端的重新验证。) [...] 服务器应该发送 must-revalidate 指令当且仅当未能重新验证对实体的请求可能导致错误操作,例如静默未执行的金融交易。

这就是这些指令的预期含义。

但与往常一样,现实情况略有不同:尤其是 must-revalidate 并不仅仅被解释为仅在缓存响应变得陈旧之后才重新验证它,而是必须在每个后续请求中重新验证它或者它根本不能被缓存(这可能是它在后续请求中发送Cache-Control: max-age=0 的原因)。

“From Cache: false”似乎表明响应不是来自缓存,而是直接来自服务器。

【讨论】:

以上是关于如何使用控制缓存标头?的主要内容,如果未能解决你的问题,请参考以下文章

由于缓存控制标头,如何绕过 Internet Explorer 11 忽略我的字体?

如何在亚马逊云端设置缓存控制标头?

如何通过 ebextensions 配置文件添加 nginx 缓存控制标头?

如何禁用 Angular 服务工作者的预检缓存控制标头(调用事件流时)?

如何使用 Spring Security 注入默认安全标头

如何设置清漆缓存控制头