Php 更新css后强制浏览器重新加载css

Php 更新css后强制浏览器重新加载css,php,css,cakephp,caching,browser-state,Php,Css,Cakephp,Caching,Browser State,当我在服务器上更新css文件时,许多客户端浏览器将在相当长的一段时间内继续使用旧的缓存css文件加载页面 在搜索了许多帖子并把不同的想法放在一起之后,我找到了一种似乎最简单、最便宜的方法 在链接任何css文件的地方,将href附加上文件最后修改日期的时间戳,如下所示: <link rel="stylesheet" type="text/css" href="main.css?t=<?=filemtime('main.css')?>" /> 我认为你的方法没有任何问题。更

当我在服务器上更新css文件时,许多客户端浏览器将在相当长的一段时间内继续使用旧的缓存css文件加载页面

在搜索了许多帖子并把不同的想法放在一起之后,我找到了一种似乎最简单、最便宜的方法

在链接任何css文件的地方,将
href
附加上文件最后修改日期的时间戳,如下所示:

<link rel="stylesheet" type="text/css" href="main.css?t=<?=filemtime('main.css')?>" />

我认为你的方法没有任何问题。更常见的情况是,这称为缓存破坏或缓存失效

但是,因为您使用的url是:
http://site.com/assets/mystyle.css?29320202020
,CDN可能存在问题。CDN将看到GET参数并认为这是一个动态请求,因此它将向您的服务器请求该文件,这与在CDN中缓存副本的目的背道而驰

我之所以这样做是因为我在文件名中包含了缓存破坏参数:
http://site.com/assets/mystyle.2390202202.css
。我正在使用优秀的工具来实现这一点,并且刚刚编写了一些简单的代码,以便我的模板知道它需要
mystyle.css
mystyle.23902022.css
由Assetic动态生成并插入到模板中

这种方法应该可以在很好地处理CDN的同时使您获得破坏缓存的功能性


其他可能的解决办法:

  • ETag:浏览器将使用ETag向服务器发送请求(可以认为是文件的散列),如果文件没有更改,服务器将使用未修改的头响应进行响应。缺点:仍然需要发出HTTP请求

  • 设置expires标头:服务器将告诉浏览器文件将在某个日期过期,如果该日期尚未过期,浏览器将不会从服务器请求副本并使用其本地缓存副本。缺点:如果服务器上的文件在日期之前更改,浏览器用户将需要手动进行硬刷新


这就是为什么我更喜欢使用缓存破坏参数:我可以将文件的expires头设置为5年后过期。浏览器永远不应该对该文件发出http请求,除非我更新该文件并更改缓存破坏参数。

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

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

根据该文件,这将

将带有上次修改时间的时间戳应用于静态资产(js, css,图像)。将附加一个包含时间的querystring参数 该文件已被修改。这对于使浏览器缓存无效非常有用


这是一个非常简单的方法,并且在大多数情况下都会起作用,但是它并不是万无一失的。大多数代理不会缓存URL中带有“?”的资源,因此如果要解决这些问题,您应该实施一个更复杂的解决方案,如phpdev建议的解决方案。

对于第二个问题:不,不是。事实上,它更像是一种约定(如果还没有的话)。对于支持它的设备,您可以在清单文件中创建和管理时间(请参阅教程:。然而,附加的时间戳被广泛使用,并且可能是一个更好的解决方案。这有助于搜索谷歌。查询字符串是否会导致浏览器每次下载文件?我会用它做一些测试。我很犹豫是否接受这个答案,因为我仍然认为应该有更好的方法告诉浏览器该文件有新版本,而不是使用php框架来重命名它。用其他可能的解决方案更新了我的答案,但我觉得破坏缓存可能是最好/最有效的方法。:)
//Configure::write('Asset.timestamp', true);