问题
有一个很少改变的项目(foo.js)。我希望这个项目存储在浏览器的缓存中(使用Expires头)。但是,当它确实发生变化时,我希望浏览器更新到最新版本。
尝试
返回Foo.js,其中包含远期的Expires标头。它缓存在浏览器上,不需要往返服务器查询。就像我喜欢它的方式。现在,当它发生变化时......
我们假设我知道用户的foo.js版本已经过时了。我怎样才能强制获得它的新副本?我使用xhr对foo.js执行POST 。理论上,这应该迫使浏览器获得更新版本的foo.js。
不幸的是,这似乎只适用于Firefox。其他浏览器将使用其副本的缓存版本,即使设置了其他POST参数。
WTF
首先,有没有办法做我想做的事情?
其次,为什么浏览器没有合理的键/值类型的缓存?为什么我不能简单地不包含在标题中:“Cache:some_key,some_expiration_time”并且还指定“Clear-Cache:key1,key2,key3”(当然,键必须是特定于域的)。相反,我们仍然坚持要求“内容新的?”的昂贵的往返旅行,或荒谬的“猜测在你修改某些东西之前它会有多久”Expires标题。
感谢
非常感谢对此事的任何评论。
编辑
答案 0 :(得分:2)
你可以只在文件的末尾添加一个查询字符串,服务器可以忽略它,但是浏览器不能,它必须将它视为新的请求:
http://www.site.com/foo.js?v=1.12345
很多人使用这种方法,SO使用某种哈希,我使用内部版本号(因此用户每次构建都会得到一个新版本)。如果其中任何一个都是一个选项,您将获得长持续时间缓存标头的好处,但仍然需要在需要时强制获取新副本。
答案 1 :(得分:0)
为什么将来设置缓存到期?例如,如果将其设置为一天,那么您将产生的唯一开销(每天一次)是浏览器重新验证它是同一个文件。如果您还没有更改它,那么您将不会重新下载该文件,服务器将以未修改的响应进行响应。
所有缓存都有一套规则 他们用来确定何时服务 缓存中的表示,如果是的话 可用。其中一些规则已经确定 在协议(HTTP 1.0和1.1)中, 有些是由管理员设定的 缓存(或者是用户) 浏览器缓存或代理 管理员)。
一般来说,这些是最多的 遵循的共同规则(不要 担心,如果你不明白 细节,将在下面解释):
- 如果响应的标题告诉缓存不保留它,则不会。
- 如果请求经过身份验证或安全(即HTTPS),则不会 缓存。
- 缓存的表示被认为是新鲜的(也就是说,可以是 发送给客户而不检查 如果: *它有一个到期时间或其他年龄控制标头集,和 仍处于新的时期,或 *如果缓存最近已经看到了代表,那就是 相对很久以前修改过。 新的表示直接从缓存中提供,没有 检查原始服务器。
- 如果陈述过时,将要求原始服务器 验证它,或告诉缓存是否 它的副本仍然很好。
- 在某些情况下 - 例如,当它断开连接时 来自网络 - 缓存可以服务 陈旧的回答,没有检查 原始服务器。
醇>如果没有验证器(ETag或 最后修改的标题)出现在a上 响应,它没有任何 明确的新鲜度信息,它 通常 - 但不总是 - 是 被认为是不可救药的。
一起,新鲜和验证 缓存最重要的方式 适用于内容。一个新鲜的 代表将可用 即时从缓存,而一个 经过验证的代表将避免 发送整个表示 再次,如果它没有改变。
答案 2 :(得分:0)
在这个帖子中提出了一个很好的建议:How can I make the browser see CSS and Javascript changes?
请参阅用户接受的答案“grom”。
我们的想法是使用服务器上的“修改”时间戳来记录文件何时被修改,并在URL的末尾添加一个版本参数,使您的CSS和JS文件具有以下URL:{ {1}}
这使得浏览器认为它是一个新文件,因此它不会引用缓存版本。
我在我的应用中使用了类似的方法。它工作得很好。当然,这会假设你使用像PHP这样的东西来处理你的HTML。
这是另一个链接,其中包含更简单的WordPress实现:http://markjaquith.wordpress.com/2009/05/04/force-css-changes-to-go-live-immediately/
答案 3 :(得分:0)
有了这些限制,我猜你唯一的选择是使用window.location.reload(true)并强制浏览器刷新所有缓存的项目..它不是很漂亮
答案 4 :(得分:0)
您可以使用 Cache-Control
HTML 标头使特定网址上的缓存无效。
在您想要的 URL 上,您可以运行(例如使用 xhr/ajax)带有以下标头的请求:
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
Pragma: 'no-cache',
Expires: '0',
}
您的缓存将失效,下一个 GET 请求将返回一个全新的结果。