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

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

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


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

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

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

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


当前回答

谷歌Chrome浏览器有硬加载以及空缓存和硬加载选项。在“检测模式”下,按住重装按钮可以选择一个。

其他回答

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

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

简单的客户端技术

一般来说,缓存是好的…所以有一些技术,取决于你是在开发网站时为自己解决问题,还是在生产环境中控制缓存。

一般访问者不会有相同的体验,当你在开发网站时。由于一般访问者访问站点的频率较低(可能每个月只有几次,除非您是谷歌或hi5 Networks),那么他们不太可能将您的文件保存在缓存中,这可能就足够了。

如果你想强制一个新版本进入浏览器,你可以在请求中添加一个查询字符串,并在你进行重大更改时增加版本号:

<script src="/myJavascript.js?version=4"></script>

这将确保每个人都获得新文件。它可以工作,因为浏览器会查看文件的URL,以确定缓存中是否有副本。如果您的服务器没有设置为对查询字符串执行任何操作,那么它将被忽略,但是对于浏览器来说,该名称将看起来像一个新文件。

另一方面,如果您正在开发一个网站,您不希望每次保存对开发版本的更改时都更改版本号。那太乏味了。

所以当你在开发你的网站时,一个很好的技巧是自动生成一个查询字符串参数:

<!-- Development version: -->
<script>document.write('<script src="/myJavascript.js?dev=' + Math.floor(Math.random() * 100) + '"\><\/script>');</script>

在请求中添加一个查询字符串是一个资源版本化的好方法,但对于一个简单的网站来说,这可能是不必要的。记住,缓存是一件好事。

It's also worth noting that the browser isn't necessarily stingy about keeping files in cache. Browsers have policies for this sort of thing, and they are usually playing by the rules laid down in the HTTP specification. When a browser makes a request to a server, part of the response is an Expires header... a date which tells the browser how long it should be kept in cache. The next time the browser comes across a request for the same file, it sees that it has a copy in cache and looks to the Expires date to decide whether it should be used.

信不信由你,实际上是你的服务器使浏览器缓存如此持久。您可以调整服务器设置并更改Expires报头,但我上面写的小技巧可能是一种更简单的方法。由于缓存很好,所以您通常希望将日期设置为遥远的将来(“far -future Expires Header”),并使用上面描述的技术强制更改。

如果你想了解更多关于HTTP的信息或者这些请求是如何发出的,一本很好的书是Steve Souders的《高性能网站》。这是对这门学科很好的介绍。

谷歌Chrome浏览器有硬加载以及空缓存和硬加载选项。在“检测模式”下,按住重装按钮可以选择一个。

对于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,但如果不需要,可以将其关闭。

另一个关于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>