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

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

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


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

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

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

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


当前回答

如果使用jQuery,有一个叫做缓存的选项,它会附加一个随机数。

我知道这不是一个完整的答案,但它可能会节省你一些时间。

其他回答

我发现在资源URL中使用基于时间戳或哈希的区分器的方法存在一个问题,该方法在服务器请求时被剥离。包含样式表链接的页面也会被缓存。因此,缓存的页面可能会请求较旧版本的样式表,但它将得到最新版本,这可能与请求页面不兼容,也可能与请求页面不兼容。

To fix this, you either have to guard the requesting page with a no-cache header or meta, to make sure it gets refreshed on every load. Or you have to maintain all versions of the style file that you ever deployed on the server, each as an individual file and with their differentiator intact so that the requesting page can get at the version of the style file it was designed for. In the latter case, you basically tie the versions of the HTML page and the style sheet together, which can be done statically and doesn't require any server logic.

有趣的文章。阅读了这里所有的答案,并结合我从未遇到过任何“伪”查询字符串问题的事实(我不确定为什么每个人都不愿意使用这个),我猜解决方案(它消除了Apache重写规则的需要,因为在接受的答案)是计算CSS文件内容的短哈希(而不是文件日期时间)作为伪查询字符串。

这将导致以下结果:

<link rel="stylesheet" href="/css/base.css?[hash-here]" type="text/css" />

当然,datetime解决方案也可以在编辑CSS文件的情况下完成工作,但我认为这是关于CSS文件的内容,而不是关于文件datetime,所以为什么要把这些混为一谈呢?

在ASP。NET Core你可以通过添加'asp-追加-版本'来实现:

<link rel="stylesheet" href="~/css/xxx.css" asp-append-version="true" />

 <script src="~/js/xxx.js" asp-append-version="true"></script>

它将生成HTML:

<link rel="stylesheet" href="/css/xxx.css?v=rwgRWCjxemznsx7wgNx5PbMO1EictA4Dd0SjiW0S90g" />

每当您更新文件时,框架将生成一个新的版本号。

仅在纯JavaScript的本地开发中禁用script.js的缓存。

它会注入一个随机的script.js?Wizardry =1231234并阻塞常规script.js:

<script type="text/javascript">
  if(document.location.href.indexOf('localhost') !== -1) {
    const scr = document.createElement('script');
    document.setAttribute('type', 'text/javascript');
    document.setAttribute('src', 'scripts.js' + '?wizardry=' + Math.random());
    document.head.appendChild(scr);
    document.write('<script type="application/x-suppress">'); // prevent next script(from other SO answer)
  }
</script>

<script type="text/javascript" src="scripts.js">

如果你添加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>