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

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

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


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

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

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

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


当前回答

另一个关于ASP的建议。网的网站,

Set different cache-control:max-age values, for different static files. For CSS and JavaScript files, the chances of modifying these files on server is high, so set a minimal cache-control:max-age value of 1 or 2 minutes or something that meets your need. For images, set a far date as the cache-control:max-age value, say 360 days. By doing so, when we make the first request, all static contents are downloaded to client machine with a 200-OK response. On subsequent requests and after two minutes, we see 304-Not Modified requests on CSS and JavaScript files which avoids us from CSS and JavaScript versioning. Image files will not be requested as they will be used from cached memory till the cache expires. By using the below web.config configurations, we can achieve the above described behavior, <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> <staticContent> <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="00.00:01:00"/> </staticContent> <httpProtocol> <customHeaders> <add name="ETAG" value=""/> </customHeaders> </httpProtocol> </system.webServer> <location path="Images"> <system.webServer> <staticContent> <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="180.00:00:00" /> </staticContent> </system.webServer> </location>

其他回答

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

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

在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" />

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

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

对于开发:使用浏览器设置:例如,Chrome网络选项卡有一个禁用缓存选项。

对于生产:使用服务器端呈现框架或纯JavaScript代码将唯一的查询参数附加到请求(例如,q?Date.now())。

// Pure JavaScript unique query parameter generation
//
//=== myfile.js

function hello() { console.log('hello') };

//=== end of file

<script type="text/javascript">
    document.write('<script type="text/javascript" src="myfile.js?q=' + Date.now() + '">
    // document.write is considered bad practice!
    // We can't use hello() yet
</script>')

<script type="text/javascript">
    hello();
</script>

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

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

?$Now.Format(dmYHis)

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