处理此问题的正确方法是更改资源的 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> 标签添加到您的页面时,会使用散列名称
- 当请求哈希命名文件时,它服务于原始资源
- 以哈希命名的文件被“永久”缓存
此设置的好处在于您不必担心是否正确缓存 - 只需将文件设置为永久缓存,哈希应该会根据内容处理可用的文件/映射。它还提供了已经缓存和快速加载的回滚/撤消功能。