在服务器被推送到代码库的更新后,是否有办法强制网页的客户端重新加载缓存(即图像,javascript等)?我们收到很多帮助台电话询问为什么某些功能不再有效。一个简单的硬刷新修复了下载新更新的javascript文件时的问题。
我们使用的是Glassfish 3.x。和JSF 2.1.x.这当然不仅仅适用于JSF。
描述我希望可行的行为:
网站A有两个图片和两个javascript文件。用户访问该站点并缓存4个文件。就我而言,除非用户专门强制“硬”刷新或清除其缓存,否则无需“重新下载”所述文件。一旦站点被推送到其中一个文件的更新,服务器可以在标题中具有某种元数据,通知客户端所述更新。如果客户选择,则会下载新文件。
我不想做的是将meta-tag放在页面的标题中以强迫任何东西不被缓存......我只是想要一些告诉客户端已经发生更新的东西,它应该得到最新的一旦更新了什么。我想这只是客户端的某种版本。
谢谢你的时间!
答案 0 :(得分:12)
处理此问题的正确方法是更改资源的URL约定。例如,我们将其作为:
/resources/js/fileName.js
要让浏览器仍然缓存文件,但是通过版本控制以正确的方式执行,是通过向URL添加内容。向查询字符串添加值不允许缓存,因此放置它的位置在/resources/
之后。
查询字符串缓存的参考:http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9
例如,您的网址如下所示:
/resources/1234/js/fileName.js
所以你可以做的是使用项目的版本号(或者当你想要重新加载缓存文件时手动更改的属性/配置文件中的某个值),因为这个数字应仅更改当项目被修改时。所以你的网址可能如下:
/resources/cacheholder${project.version}/js/fileName.js
这应该很容易。
现在的问题是映射URL,因为中间的值是动态的。我们克服的方式是使用URL重写模块,允许我们在到达应用程序之前过滤URL。对于看起来像这样的URL的重写进行了重写:
/resources/cacheholder______/whatever
删除了cacheholder_______/
部分。在重写之后,它看起来像一个正常的请求,服务器将使用正确的文件进行响应,而没有任何其他特定的映射/逻辑...重点是浏览器认为它是一个新文件(即使它真的不是' t),所以它请求它,并且服务器将其计算出来并提供正确的文件(即使它是一个“奇怪的”URL)。
当然,另一种选择是将此动态字符串添加到文件名本身,然后使用重写工具将其删除。无论哪种方式,都做了同样的事情 - 在重写期间定位一串文本并删除它。这允许你欺骗浏览器,但不能欺骗服务器:)
<强>更新强>
我真正喜欢的另一种方法是根据内容设置文件名,并缓存它。例如,可以使用哈希来完成。当然,这种类型的东西不是你手动做的事情并保存到你的项目中(希望如此);这是你的应用程序/框架应该处理的东西。例如,在Grails中,有一个“哈希和缓存”资源的插件,因此会发生以下情况:
<script>
/ <link>
代码时,会使用散列名称这个设置有什么好处,你不必担心正确缓存 - 只需将文件设置为永久缓存,并且散列应该根据内容处理可用的文件/映射。它还提供了已经快速缓存和加载回滚/撤消的功能。
答案 1 :(得分:0)
我在这种情况下使用no-cache参数... a有一个字符串常量值,如(来自配置文件)
$no_cache = "v11";
在页面中,我使用像
这样的资产<img src="a.jpg?nc=$no_cache">
当我更新我的代码时,只需更改$ no_cache值,它就像魅力一样。