当我更新服务器上的css文件时,许多客户端浏览器将继续使用旧的缓存css文件加载页面很长一段时间。
在搜索了很多帖子并将不同的想法放在一起之后,我想出了一种似乎最简单和最便宜的方法。
在链接任何css文件的情况下,将href
附加文件的最后修改日期的时间戳,如下所示:
<link rel="stylesheet" type="text/css" href="main.css?t=<?=filemtime('main.css')?>" />
我正在使用CakePHP,所以我在布局文件中做的是:
<? $t = filemtime(CSS . 'main.css'); ?>
<?=$html->css("schedule.css?t={$t}") ?>
因此,到css文件的链接末尾有一个额外的标记,但只要文件没有被修改就会保持不变。这意味着浏览器将能够像往常一样缓存它。但是,只要文件被修改,链接就会改变,浏览器也不会错过任何一个节拍。
仍然使用这种方法,让人感觉有点脏,因为它不适合用于某些东西。对于正在发送的“消息”没有用处,因为消息的内容很重要,除了识别它的存在。
以下是我的问题:
答案 0 :(得分:4)
我认为您的方法没有任何问题。更常见的是,这称为缓存清除或缓存失效。
但是,由于您使用的是诸如:http://site.com/assets/mystyle.css?29320202020
之类的网址,因此可能存在CDN问题。 CDN将看到GET参数并认为它是一个动态请求,因此它会向您的服务器询问该文件,这会破坏在CDN中拥有缓存副本的目的。
为什么我要在文件名中包含缓存清除参数:http://site.com/assets/mystyle.2390202202.css
。我使用优秀的Assetic library来执行此操作并编写了一些简单的代码,以便我的模板知道它需要mystyle.css
并且mystyle.2390202202.css
由Assetic动态生成并插入到模板中
这种方法可以让你在处理CDN时很好地缓存破坏功能。
其他可能的解决方案:
ETags:浏览器将使用ETag向服务器发送请求(可以将其视为文件的散列),如果文件未更改,服务器将使用未修改的标头响应进行响应。缺点:仍然需要发出HTTP请求。
设置过期标题:服务器将告诉浏览器该文件将在特定日期过期,如果还不是该日期,则浏览器不会从服务器请求副本并使用其本地缓存副本。缺点:如果服务器上的文件在日期之前发生变化,浏览器的用户将需要手动进行硬刷新。
这就是为什么我更喜欢使用缓存清除参数:我可以将文件的expires头设置为在5年后到期。浏览器不应该对该文件发出http请求,除非我更新文件并更改缓存清除参数。
答案 1 :(得分:4)
CakePHP有一个非常简单易用的解决方案。只需取消注释这一行:
//Configure::write('Asset.timestamp', true);
来自core.php
根据该文件,这将
将上次修改时间的时间戳应用于静态资产(js, css,图像)。将附加包含时间的查询字符串参数 该文件已被修改。这对于使浏览器缓存无效非常有用。
这非常简单,大部分时间都可以使用,但并非万无一失。大多数代理都不会使用&#34;?&#34;来缓存资源。在URL中,所以如果你想修复这些情况,你应该实现一个更复杂的解决方案,就像phpdev建议的那样。