我注意到一些浏览器(特别是Firefox和Opera)非常热衷于使用.css和.js文件的缓存副本,甚至在浏览器会话之间。当您更新其中一个文件时,这会导致一个问题,但用户的浏览器会继续使用缓存的副本。
当文件发生更改时,强迫用户浏览器重新加载文件的最优雅的方法是什么?
理想情况下,该解决方案不会强制浏览器在每次访问页面时重新加载文件。
我发现John Millikin和da5id的建议很有用。这有一个专门的术语:自动版本控制。
我在下面发布了一个新的答案,这是我最初的解决方案和约翰的建议的结合。
SCdF建议的另一个想法是将伪查询字符串附加到文件中。(一些自动使用时间戳作为伪查询字符串的Python代码是由pi..提交的)
然而,关于浏览器是否缓存带有查询字符串的文件还存在一些讨论。(请记住,我们希望浏览器缓存该文件并在以后的访问中使用它。我们只希望它在文件更改时再次获取该文件。)
ASP。NET我建议以下解决方案与高级选项(调试/发布模式,版本):
以这种方式包含JavaScript或CSS文件:
<script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>" />
<link rel="stylesheet" type="text/css" href="Css/exampleCss<%=Global.CssPostfix%>" />
全球。JsPostfix和Global。在Global.asax中,CssPostfix的计算方法如下:
protected void Application_Start(object sender, EventArgs e)
{
...
string jsVersion = ConfigurationManager.AppSettings["JsVersion"];
bool updateEveryAppStart = Convert.ToBoolean(ConfigurationManager.AppSettings["UpdateJsEveryAppStart"]);
int buildNumber = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision;
JsPostfix = "";
#if !DEBUG
JsPostfix += ".min";
#endif
JsPostfix += ".js?" + jsVersion + "_" + buildNumber;
if (updateEveryAppStart)
{
Random rand = new Random();
JsPosfix += "_" + rand.Next();
}
...
}
对于Java Servlet环境,可以查看Jawr库。功能页面解释了它是如何处理缓存的:
Jawr will try its best to force your clients to cache the resources. If a browser asks if a file changed, a 304 (not modified) header is sent back with no content. On the other hand, with Jawr you will be 100% sure that new versions of your bundles are downloaded by all clients. Every URL to your resources will include an automatically generated, content-based prefix that changes automatically whenever a resource is updated. Once you deploy a new version, the URL to the bundle will change as well so it will be impossible that a client uses an older, cached version.
该库还可以简化JavaScript和CSS,但如果不需要,可以将其关闭。