2012-04-16 173 views
3

当我更新服务器上的css文件时,许多客户端浏览器将继续使用旧的缓存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文件对最终的额外的标签,但它保持不变,只要文件没有被修改。这意味着浏览器可以像往常一样缓存它。然而,一旦文件被修改,链接将改变,并且浏览器不会错过节拍。

仍然使用这种方法,对于使用某些没有意图的东西,感觉有点脏。对于正在发送的“消息”是没有用的,因为消息的内容很重要,而不是识别它的存在。

这里是我的问题:

  1. 是否可以承认有客户看到修改后的HTML与浏览器缓存过时的样式表(或JavaScript为此事)的风险?
  2. 这是一个黑客或合法的解决方案?
  3. 有没有更好的解决方案?
+0

对于第二个问题:不,它不是。事实上,它更像是成为一种惯例(如果还没有的话)。 – 2012-04-16 01:10:12

+0

对于支持它的设备,您可以在清单文件上创建和管理时间(请参阅教程:http://www.html5rocks.com/en/tutorials/appcache/beginner/)。附加的时间戳被广泛使用,然而,可能是一个更好的解决方案。 – rjz 2012-04-16 01:11:50

回答

4

我不认为你的方法有任何问题。更常见的是,这被称为缓存清除或缓存失效。

但是,由于您使用的网址如:http://site.com/assets/mystyle.css?29320202020,因此CDN可能存在问题。 CDN会看到GET参数,并认为它是一个动态请求,所以它会向你的服务器请求文件,这违背了在CDN中有一个缓存副本的目的。

为什么我要做的是将缓存清除参数包含在我的文件名中:http://site.com/assets/mystyle.2390202202.css。我使用优秀的Assetic library来做到这一点,并且只写了一些简单的代码,以便我的模板知道它需要mystyle.cssmystyle.2390202202.css由Assetic实时生成并插入到模板中。

这种方法应该能让你在处理CDN时很好地缓存清除功能。


其他可能的解决方案:

  • 的ETag:浏览器将发送到与ETag的服务器发送一个请求(可鑫卡特作为文件的哈希),而服务器将响应如果文件没有改变,则没有修改的标题响应。下行:仍然需要HTTP请求。

  • 设置expires标题:服务器会告诉浏览器该文件将在特定日期到期,如果该日期还没有,浏览器将不会向服务器请求副本并使用其本地缓存复制。缺点:如果服务器上的文件在日期之前发生变化,浏览器的用户将需要手动进行硬刷新。

这就是为什么我宁愿只使用一个缓存无效参数:我可以设置expires头的文件,以在5年内到期。浏览器不应该为该文件发出http请求,除非我更新文件并更改缓存清除参数。

+0

+1表示“缓存清除”。这有助于搜索谷歌。查询字符串是否会导致浏览器每次下载文件?我会做一些测试。我很犹豫是否接受这个答案,因为我仍然认为应该有一种更好的方式来告诉浏览器该文件的新版本比使用php框架来重命名它更新。 – 2012-04-16 19:07:25

+0

用其他可能的解决方案更新了我的答案,但我认为缓存清除可能是最好/最有效的。 :) – F21 2012-04-16 23:27:05

4

CakePHP有一个非常简单的解决方案。只是取消注释这一行:

//Configure::write('Asset.timestamp', true); 

core.php

根据该文件,这将

应用时间戳与最后修改时间静态资产(JS,0​​CSS,图像)。将添加包含时间 的querystring参数该文件已被修改。这对于使浏览器缓存失效很有用。

这是非常简单的工作,并且大部分时间都可以工作,但它不是万无一失的。大多数代理不会使用“?”来缓存资源在URL中,所以如果你想解决这些情况,你应该实现一个更复杂的解决方案,就像phpdev所建议的那样。

+0

哇,谢谢。很高兴知道关于蛋糕! – 2012-05-16 15:00:30

相关问题