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

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

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


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

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

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

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


当前回答

对于在开发和测试时遇到此问题的开发人员:

简单地删除缓存。

“保持缓存与文件一致”..太麻烦了。

一般来说,我不介意加载更多的文件——甚至在大多数项目中加载没有改变的文件——实际上是无关紧要的。在开发应用程序时,我们主要从磁盘加载,在localhost:port上加载,因此网络流量的增加不是一个棘手的问题。

大多数小项目只是玩玩而已——它们从来没有真正投入生产。所以对他们来说,你不需要更多的东西……

因此,如果你使用Chrome DevTools,你可以遵循如下图所示的禁用缓存方法:

如果你有Firefox缓存问题:

只在开发过程中这样做。你还需要一种机制来强制重新加载用于生产,因为如果你频繁地更新你的应用程序,你的用户将使用旧的缓存失效的模块,而你没有提供一个专门的缓存同步机制,就像上面的答案中描述的那样。

是的,这个信息已经在以前的答案中,但我仍然需要做谷歌搜索才能找到它。

其他回答

RewriteRule需要对JavaScript或CSS文件进行一个小的更新,这些文件最后包含点符号版本控制。例如,json-1.3.js。

我添加了一个点否定类[^。]转换为正则表达式,即.number。将被忽略。

RewriteRule ^(.*)\.[^.][\d]+\.(css|js)$ $1.$2 [L]

我不知道为什么你们要花这么大的力气来实现这个解决方案。

您所需要做的就是获取文件修改后的时间戳,并将其作为查询字符串附加到文件中。

在PHP中,我会这样做:

<link href="mycss.css?v=<?= filemtime('mycss.css') ?>" rel="stylesheet">

filemtime()是一个PHP函数,返回修改后的文件时间戳。

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

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

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

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

静态文件的简单解决方案(仅用于开发目的),使用脚本标记注入将随机版本号添加到脚本URI

<script>
    var script = document.createElement('script');
    script.src = "js/app.js?v=" + Math.random();
    document.getElementsByTagName('head')[0].appendChild(script);
</script>

TomA的回答是对的。

使用“querystring”方法将不会被缓存,Steve Souders引用如下:

...Squid,一个流行的代理,不缓存资源 变量的名称。

TomA建议使用style.TIMESTAMP.css很好,但是MD5会更好,因为只有当内容真正改变时,MD5也会改变。