我注意到一些浏览器(特别是Firefox和Opera)非常热衷于使用.css和.js文件的缓存副本,甚至在浏览器会话之间。当您更新其中一个文件时,这会导致一个问题,但用户的浏览器会继续使用缓存的副本。
当文件发生更改时,强迫用户浏览器重新加载文件的最优雅的方法是什么?
理想情况下,该解决方案不会强制浏览器在每次访问页面时重新加载文件。
我发现John Millikin和da5id的建议很有用。这有一个专门的术语:自动版本控制。
我在下面发布了一个新的答案,这是我最初的解决方案和约翰的建议的结合。
SCdF建议的另一个想法是将伪查询字符串附加到文件中。(一些自动使用时间戳作为伪查询字符串的Python代码是由pi..提交的)
然而,关于浏览器是否缓存带有查询字符串的文件还存在一些讨论。(请记住,我们希望浏览器缓存该文件并在以后的访问中使用它。我们只希望它在文件更改时再次获取该文件。)
在Laravel (PHP)中,我们可以以以下清晰而优雅的方式(使用文件修改时间戳)做到这一点:
<script src="{{ asset('/js/your.js?v='.filemtime('js/your.js')) }}"></script>
CSS也是如此
<link rel="stylesheet" href="{{asset('css/your.css?v='.filemtime('css/your.css'))}}">
示例HTML输出(filemtime返回时间作为Unix时间戳)
<link rel="stylesheet" href="assets/css/your.css?v=1577772366">
如果你添加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>
我们有一个解决方案,有一些不同的实现方式。我们使用上面的解决方案。
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也会更改,因此文件的版本将会更改,并且在下次打开浏览器时,它会检测到一个新文件并获取它。