javascript 网站更新后强制浏览器重新加载所有缓存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15936050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Force browser to reload all cache after site update
提问by Mickelback
Is there a way to force the clients of a webpage to reload the cache (i.e. images, javascript, etc) after a server has been pushed an update to the code base? We get a lot of help desk calls asking why certain functionality no longer works. A simple hard refresh fixes the problems as it downloads the newly updated javascript file.
在服务器已将更新推送到代码库后,有没有办法强制网页的客户端重新加载缓存(即图像、javascript 等)?我们接到了很多服务台电话,询问为什么某些功能不再有效。在下载新更新的 javascript 文件时,简单的硬刷新可以解决问题。
For specifics we are using Glassfish 3.x. and JSF 2.1.x. This would apply to more than just JSF of course.
具体来说,我们使用的是 Glassfish 3.x。和 JSF 2.1.x。这当然不仅仅适用于 JSF。
To describe what behavior I hope is possible:
描述我希望什么行为是可能的:
Website A has two images and two javascript files. A user visits the site and the 4 files get cached. As far as I'm concerned, no need to "re-download" said files unless user specifically forces a "hard" refresh or clears their cache. Once a site is pushed an update to one of the files, the server could have some sort of metadata in the header informing the client of said update. If the client chooses, the new files would be downloaded.
网站 A 有两张图片和两个 javascript 文件。用户访问该站点,4 个文件被缓存。就我而言,除非用户特别强制“硬”刷新或清除其缓存,否则无需“重新下载”所述文件。一旦站点被推送到其中一个文件的更新,服务器可能会在标题中包含某种元数据,通知客户端所述更新。如果客户端选择,将下载新文件。
What I don't want to do is put meta-tag in the header of a page to force nothing from ever being cached...I just want something that tells the client an update has occurred and it should get the latest once something has been updated. I suppose this would just be some sort of versioning on the client side.
我不想做的是将元标记放在页面的标题中以强制缓存任何内容......我只是想要一些告诉客户端更新已经发生的东西,一旦有东西它应该得到最新的已更新。我想这只是客户端的某种版本控制。
Thanks for your time!
谢谢你的时间!
回答by Ian
The correct way to handle this is with changing the URL convention for your resources. For example, we have it as:
处理此问题的正确方法是更改资源的 URL 约定。例如,我们将其定义为:
/resources/js/fileName.js
To get the browser to still cache the file, but do it the proper way with versioning, is by adding something to the URL. Adding a value to the querystring doesn't allow caching, so the place to put it is after /resources/
.
要让浏览器仍然缓存文件,但使用版本控制的正确方法是向 URL 添加一些内容。向查询字符串添加值不允许缓存,因此放置它的位置在/resources/
.
A reference for querystring caching: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9
查询字符串缓存的参考:http: //www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9
So for example, your URLs would look like:
例如,您的网址如下所示:
/resources/1234/js/fileName.js
So what you could do is use the project's version number (or some value in a properties/config file that you manually change when you want cached files to be reloaded) since this number shouldchange only when the project is modified. So your URL could look like:
因此,您可以做的是使用项目的版本号(或在您希望重新加载缓存文件时手动更改的属性/配置文件中的某个值),因为该编号仅在修改项目时才应更改。所以你的 URL 可能看起来像:
/resources/cacheholder${project.version}/js/fileName.js
That should be easy enough.
那应该很容易。
The problem now is with mapping the URL, since that value in the middle is dynamic. The way we overcame that is with a URL rewriting module that allowed us to filter URLs before they got to our application. The rewrite watched for URLs that looked like:
现在的问题是映射 URL,因为中间的那个值是动态的。我们克服的方法是使用 URL 重写模块,该模块允许我们在 URL 到达我们的应用程序之前对其进行过滤。重写监视看起来像的 URL:
/resources/cacheholder______/whatever
And removed the cacheholder_______/
part. After the rewrite, it looked like a normal request, and the server would respond with the correct file, without any other specific mapping/logic...the point is that the browser thought it was a new file (even though it really wasn't), so it requested it, and the server figures it out and serves the correct file (even though it's a "weird" URL).
并删除了cacheholder_______/
部分。重写后,它看起来像一个正常的请求,服务器会以正确的文件响应,没有任何其他特定的映射/逻辑......关键是浏览器认为它是一个新文件(即使它确实不是) t),所以它请求它,服务器计算出来并提供正确的文件(即使它是一个“奇怪的”URL)。
Of course, another option is to add this dynamic string to the filename itself, and then use the rewrite tool to remove it. Either way, the same thing is done - targeting a string of text during rewrite, and removing it. This allows you to fool the browser, but not the server :)
当然,另一种选择是将此动态字符串添加到文件名本身,然后使用重写工具将其删除。无论哪种方式,都完成了相同的事情 - 在重写期间针对文本字符串并将其删除。这允许你欺骗浏览器,而不是服务器:)
UPDATE:
更新:
An alternative that I really like is to set the filename based on the contents, and cache that. For example, that could be done with a hash. Of course, this type of thing isn't something you'd manually do and save to your project (hopefully); it's something your application/framework should handle. For example, in Grails, there's a plugin that "hashes and caches" resources, so that the following occurs:
我真正喜欢的另一种方法是根据内容设置文件名,并缓存它。例如,这可以通过散列来完成。当然,这类事情不是您手动执行并保存到项目中的(希望如此);这是您的应用程序/框架应该处理的事情。例如,在 Grails 中,有一个插件可以“散列和缓存”资源,因此会发生以下情况:
- Every resource is checked
- A new file (or mapping to this file) is created, with a name that is the hash of its contents
- When adding
<script>
/<link>
tags to your page, the hashed name is used - When the hash-named file is requested, it serves the original resource
- The hash-named file is cached "forever"
- 每个资源都被检查
- 创建一个新文件(或映射到该文件),其名称是其内容的哈希值
- 向页面添加
<script>
/<link>
标签时,使用散列名称 - 当请求哈希命名的文件时,它提供原始资源
- 哈希命名的文件被“永远”缓存
What's cool about this setup is that you don't have to worry about caching correctly - just set the files to cache forever, and the hashing should take care of files/mappings being available based on content. It also provides the ability for rollbacks/undos to already be cached and loaded quickly.
这种设置的好处在于您不必担心正确缓存 - 只需将文件设置为永久缓存,并且散列应该根据内容处理可用的文件/映射。它还提供了回滚/撤消已经被缓存和快速加载的能力。
回答by tanaydin
i use a no-cache parameter for this situations... a have a string constant value like (from config file)
我在这种情况下使用 no-cache 参数......有一个字符串常量值,如(来自配置文件)
$no_cache = "v11";
and in pages, i use assets like
在页面中,我使用类似的资产
<img src="a.jpg?nc=$no_cache">
and when i update my code, just change the $no_cache value, and it works like a charm.
当我更新我的代码时,只需更改 $no_cache 值,它就像一个魅力。