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

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

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


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

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

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

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


当前回答

对于我的开发,我发现Chrome有一个很好的解决方案。

https://superuser.com/a/512833

随着开发人员工具的打开,只需长按刷新按钮,让放手一旦你悬停在“空缓存和硬加载”。

这是我最好的朋友,是一种超轻量级的方式来得到你想要的!

其他回答

更改文件名也可以。但这通常不是最简单的解决方案。

正如你所注意到的,HTTP缓存控制标头为“no-cache”并不总是有效。HTTP 1.1规范为用户代理提供了决定是否请求新副本的回旋余地。(如果只看指令的名称,这是不直观的。去阅读实际的HTTP 1.1缓存规范…这在上下文中更有意义。)

简而言之,如果你想要严格的缓存控制使用

Cache-Control: no-cache, no-store, must-revalidate

在响应头中。

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.

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

我没有发现客户端DOM方法动态创建脚本节点(或CSS)元素:

<script>
    var node = document.createElement("script");
    node.type = "text/javascript";
    node.src = 'test.js?' + Math.floor(Math.random()*999999999);
    document.getElementsByTagName("head")[0].appendChild(node);
</script>

一个特定于silverstripe的答案是:http://api.silverstripe.org/3.0/source-class-SS_Datetime.html#98-110:

希望这将帮助使用SilverStripe模板的人,并试图在每次页面访问/刷新时强制重新加载缓存图像。在我的情况下,它是一个GIF动画,只播放一次,因此没有重放后,它被缓存。在我的模板中,我简单地添加了:

?$Now.Format(dmYHis)

添加到文件路径的末尾,以创建唯一的时间戳并强制浏览器将其视为新文件。

您可以简单地添加一些随机数与CSS和JavaScript URL

example.css?randomNo = Math.random()