我可以清除浏览器缓存中的特定URL(使用POST或其他方式)吗?

时间:2010-08-24 01:34:23

标签: ajax http caching post

问题

有一个很少改变的项目(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标题。

感谢

非常感谢对此事的任何评论。

编辑

  • 我意识到在文件中添加版本号可以解决这个问题。但是,在我的情况下,这是不可能的 - 对“foo.js”的调用被硬编码到书签中。

5 个答案:

答案 0 :(得分:2)

你可以只在文件的末尾添加一个查询字符串,服务器可以忽略它,但是浏览器不能,它必须将它视为新的请求:

http://www.site.com/foo.js?v=1.12345

很多人使用这种方法,SO使用某种哈希,我使用内部版本号(因此用户每次构建都会得到一个新版本)。如果其中任何一个都是一个选项,您将获得长持续时间缓存标头的好处,但仍然需要在需要时强制获取新副本。

答案 1 :(得分:0)

为什么将来设置缓存到期?例如,如果将其设置为一天,那么您将产生的唯一开销(每天一次)是浏览器重新验证它是同一个文件。如果您还没有更改它,那么您将不会重新下载该文件,服务器将以未修改的响应进行响应。

  

所有缓存都有一套规则   他们用来确定何时服务   缓存中的表示,如果是的话   可用。其中一些规则已经确定   在协议(HTTP 1.0和1.1)中,   有些是由管理员设定的   缓存(或者是用户)   浏览器缓存或代理   管理员)。

     

一般来说,这些是最多的   遵循的共同规则(不要   担心,如果你不明白   细节,将在下面解释):

     
      
  1. 如果响应的标题告诉缓存不保留它,则不会。
  2.   
  3. 如果请求经过身份验证或安全(即HTTPS),则不会   缓存。
  4.   
  5. 缓存的表示被认为是新鲜的(也就是说,可以是   发送给客户而不检查   如果:         *它有一个到期时间或其他年龄控制标头集,和   仍处于新的时期,或         *如果缓存最近已经看到了代表,那就是   相对很久以前修改过。     新的表示直接从缓存中提供,没有   检查原始服务器。
  6.   
  7. 如果陈述过时,将要求原始服务器   验证它,或告诉缓存是否   它的副本仍然很好。
  8.   
  9. 在某些情况下 - 例如,当它断开连接时   来自网络 - 缓存可以服务   陈旧的回答,没有检查   原始服务器。
  10.         

    如果没有验证器(ETag或   最后修改的标题)出现在a上   响应,它没有任何   明确的新鲜度信息,它   通常 - 但不总是 - 是   被认为是不可救药的。

         

    一起,新鲜和验证   缓存最重要的方式   适用于内容。一个新鲜的   代表将可用   即时从缓存,而一个   经过验证的代表将避免   发送整个表示   再次,如果它没有改变。

http://www.mnot.net/cache_docs/#BROWSER

答案 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 请求将返回一个全新的结果。