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

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

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


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

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

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

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


当前回答

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

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

在PHP中,我会这样做:

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

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

其他回答

谷歌Chrome浏览器有硬加载以及空缓存和硬加载选项。在“检测模式”下,按住重装按钮可以选择一个。

ASP。NET 4.5及以上版本可以使用脚本捆绑。

The request http://localhost/MvcBM_time/bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81 is for the bundle AllMyScripts and contains a query string pair v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81. The query string v has a value token that is a unique identifier used for caching. As long as the bundle doesn't change, the ASP.NET application will request the AllMyScripts bundle using this token. If any file in the bundle changes, the ASP.NET optimization framework will generate a new token, guaranteeing that browser requests for the bundle will get the latest bundle.

捆绑还有其他好处,包括通过缩小页面来提高首次加载时的性能。

我所知道的最好和最快的方法之一是更改存放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,并使用重写规则去除版本号。

如果你添加session-id作为JavaScript/CSS文件的伪参数,你可以强制“会话范围缓存”:

<link rel="stylesheet" src="myStyles.css?ABCDEF12345sessionID" />
<script language="javascript" src="myCode.js?ABCDEF12345sessionID"></script>

如果需要版本级缓存,可以添加一些代码来打印文件日期或类似内容。如果您正在使用Java,您可以使用自定义标记以一种优雅的方式生成链接。

<link rel="stylesheet" src="myStyles.css?20080922_1020" />
<script language="javascript" src="myCode.js?20080922_1120"></script>