我注意到一些浏览器(特别是Firefox和Opera)非常热衷于使用.css和.js文件的缓存副本,甚至在浏览器会话之间。当您更新其中一个文件时,这会导致一个问题,但用户的浏览器会继续使用缓存的副本。

当文件发生更改时,强迫用户浏览器重新加载文件的最优雅的方法是什么?

理想情况下,该解决方案不会强制浏览器在每次访问页面时重新加载文件。


我发现John Millikin和da5id的建议很有用。这有一个专门的术语:自动版本控制。

我在下面发布了一个新的答案,这是我最初的解决方案和约翰的建议的结合。

SCdF建议的另一个想法是将伪查询字符串附加到文件中。(一些自动使用时间戳作为伪查询字符串的Python代码是由pi..提交的)

然而,关于浏览器是否缓存带有查询字符串的文件还存在一些讨论。(请记住,我们希望浏览器缓存该文件并在以后的访问中使用它。我们只希望它在文件更改时再次获取该文件。)


当前回答

下面是我基于Bash脚本的缓存破坏解决方案:

我假设在index.html文件中引用了CSS和JavaScript文件 在index.html中为.js和.css添加时间戳作为参数,如下所示(仅限一次) 用上面的时间戳创建一个timestamp.txt文件。 在对.css或.js文件进行任何更新后,只需运行下面的.sh脚本

带时间戳的.js和.css index.html示例条目:

<link rel="stylesheet" href="bla_bla.css?v=my_timestamp">
<script src="scripts/bla_bla.js?v=my_timestamp"></script>

文件timestamp.txt应该只包含相同的时间戳'my_timestamp'(稍后将被脚本搜索并替换)

最后这里是脚本(让我们称之为cache_buster.sh:D)

old_timestamp=$(cat timestamp.txt)
current_timestamp=$(date +%s)
sed -i -e "s/$old_timestamp/$current_timestamp/g" index.html
echo "$current_timestamp" >timestamp.txt

(Visual Studio Code用户)你可以把这个脚本放在一个钩子中,这样每次文件保存在你的工作空间时它都会被调用。

其他回答

我将文件内容的MD5哈希值放在其URL中。这样我就可以设置一个很长的过期日期,而不必担心用户使用旧的JS或CSS。

我还在运行时(或在文件系统更改时)对每个文件进行一次计算,因此在设计时或构建过程中没有什么有趣的事情要做。

如果你使用ASP。NET MVC,那么你可以在我的另一个答案中查看代码。

我这样做的方法是简单地有链接元素到服务器端包含:

<!--#include virtual="/includes/css-element.txt"-->

css-element.txt的内容在哪里

<link rel="stylesheet" href="mycss.css"/>

如果你想链接到my-new-css。css,你只需要改变include。

我所知道的最好和最快的方法之一是更改存放CSS或JavaScript文件的文件夹的名称。

或者对于开发人员:更改CSS和JavaScript文件的名称,例如版本。

<link rel="stylesheet" href="cssfolder/somecssfile-ver-1.css"/>

对JavaScript文件执行同样的操作。

不要使用foo.css?version=1!

浏览器不应该缓存带有GET变量的url。据http://www.thinkvitamin.com/features/webapps/serving-javascript-fast网站报道,尽管ie和Firefox会忽略这一点,但Opera和Safari不会!相反,使用foo.v1234.css,并使用重写规则去除版本号。

如果您使用的是现代浏览器,可以使用清单文件通知浏览器哪些文件需要更新。它不需要标头,也不需要url中的版本等等。

详情请参见: 使用应用程序缓存