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

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

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


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

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

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

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


当前回答

我们有一个解决方案,有一些不同的实现方式。我们使用上面的解决方案。

datatables?v=1

我们可以处理文件的版本。这意味着每次我们改变文件时,它的版本也会改变。但这不是一个合适的方式。

另一种方法使用GUID。它也不合适,因为每次它都从浏览器缓存中获取文件而不使用。

datatables?v=Guid.NewGuid()

最后一种最好的方法是:

当文件发生更改时,也要更改版本。检查以下代码:

<script src="~/scripts/main.js?v=@File.GetLastWriteTime(Server.MapPath("/scripts/main.js")).ToString("yyyyMMddHHmmss")"></script>

通过这种方式,当您更改文件时,LastWriteTime也会更改,因此文件的版本将会更改,并且在下次打开浏览器时,它会检测到一个新文件并获取它。

其他回答

JavaScript文件的另一种方法是使用jQuery $。与$. getScript结合使用。ajaxSetup选项缓存:false。

而不是:

<script src="scripts/app.js"></script>

你可以使用:

$.ajaxSetup({
  cache: false
});

$.getScript('scripts/app.js'); // GET scripts/app.js?_1391722802668

只需在你想要硬重载(强制浏览器重载缓存的CSS和JavaScript文件)的地方添加以下代码:

$(window).load(function() {
    location.reload(true);
});

在.load中执行此操作,这样它就不会像循环一样刷新。

仅在纯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">

如果您不想让客户端缓存文件,这个解决方案似乎是最快实现的。如果你在footer.php中加载文件,用time()调整部分:

<script src="<?php echo get_template_directory_uri(); ?>/js/main.js?v=<?= time() ?>"></script>

我建议您使用实际CSS文件的MD5散列,而不是手动更改版本。

URL应该是这样的

http://mysite.com/css/[md5_hash_here]/style.css

您仍然可以使用重写规则来去除散列,但优点是现在您可以将缓存策略设置为“永远缓存”,因为如果URL相同,这意味着文件没有改变。

然后,您可以编写一个简单的shell脚本来计算文件的散列并更新标记(您可能希望将其移动到一个单独的文件中进行包含)。

只要在CSS每次更改时运行该脚本就可以了。浏览器只会在文件被修改时重新加载。如果你做了一个编辑,然后撤销它,为了让你的访问者不重新下载,你不需要确定需要返回到哪个版本。