通过参数缓存破坏

IT技术 javascript html css caching
2021-02-06 16:17:08

我们希望在生产部署时缓存 bust,但不要浪费大量时间来找出一个系统来这样做。我的想法是将参数应用到具有当前版本号的 css 和 js 文件的末尾:

<link rel="stylesheet" href="base_url.com/file.css?v=1.123"/>

两个问题:这会有效地破坏缓存吗?param 是否会导致浏览器永远不会缓存来自该 url 的响应,因为 param 表明这是动态内容?

6个回答

参数?v=1.123表示一个查询字符串,因此浏览器会认为它是一个新的路径,比如,?v=1.0从而导致它从文件加载,而不是从缓存加载。如你所愿。

并且,浏览器会假设您下次调用时源将保持不变,?v=1.123使用该字符串缓存它。因此,无论您的服务器如何设置,它都会保持缓存状态,直到您移动到?v=1.124或以此类推。

那篇博文现在快十年了。你认为缓存提供商和 CDN 还没有适应它吗?鱿鱼似乎能够缓存与查询字符串的文件现在
2021-03-10 16:17:08
我个人不明白为什么但 Lara Hogan (Swanson)(Etsy 的工程经理)不建议使用查询参数进行缓存破坏。我认为这与用户和服务器之间的缓存代理有关。
2021-03-14 16:17:08
引用 Steve Souders 的话说:“要获得流行代理缓存的好处,请避免使用查询字符串进行 revving,而是 rev 文件名本身。” 完整的解释可以在这里找到:stevesouders.com/blog/2008/08/23/...
2021-03-18 16:17:08
也许这对某人有帮助:就个人而言,我使用文件修改时间戳作为“自动”版本参数,例如。 <link rel="stylesheet" href="style.css?v=1487935578" />
2021-04-07 16:17:08

两个问题:这会有效地破坏缓存吗?

是的。甚至 Stack Overflow 也使用这种方法,尽管我记得他们(每天有数百万的访问者以及数以百万计的不同客户端和代理版本和配置)有一些奇怪的边缘情况,即使这也不足以破坏缓存。但一般假设这是可行的,并且是一种打破客户端缓存的合适方法。

param 是否会导致浏览器永远不会缓存来自该 url 的响应,因为 param 表明这是动态内容?

不会。该参数不会改变缓存策略;服务器发送的缓存头仍然适用,如果它不发送任何,浏览器的默认值。

@spender 我读过一些代理服务器(旧的或可以配置为)在缓存时忽略查询字符串。
2021-03-14 16:17:08
@spender - 我也听说过,我认为更改文件名或路径是最好的选择。将所有静态文件移动到版本化文件夹名称下可能是最简单的,例如/static/v22/file.css,因为您可以使用单个文件夹重命名来处理多个文件,例如 /static/v23/file.css/static/v23/mystuff.js
2021-03-26 16:17:08
@spender 我恐怕现在找不到参考,有一篇很长的博客文章或 SO 答案,Jeff Atwood 谈到了它(IIRC)
2021-04-04 16:17:08

将版本号放在实际文件名中会更安全。这允许同时存在多个版本,因此您可以推出新版本,如果仍然存在任何请求旧版本的缓存 HTML 页面,他们将获得适用于其 HTML 的版本。

请注意,在 Internet 上任何地方最大的版本化部署之一中,jQuery 在实际文件名中使用版本号,并且它安全地允许多个版本共存,而无需任何特殊的服务器端逻辑(每个版本只是一个不同的文件)。

当您部署新页面和新链接文件(这是您想要的)时,这会破坏缓存一次,然后可以有效地缓存这些版本(您也想要)。

@Pekka - 版本号可以允许同时存在多个版本,但这需要服务器合作将查询参数映射到正确的实际文件。我不认为这就是 OP 在这里所做的事情,并且在修改文件名时几乎没有理由要求这种复杂性要简单得多并且不需要服务器合作。显然两者都可以工作。
2021-03-14 16:17:08
我同意这一点,但与必须单独控制每个文件相比,让 Sinatra 将 ?v=<%=VERSION%> 附加到所有 css 和 js 请求要容易得多。最终我们将切换到 sinatra-assetpack,它将对所有文件进行预处理和压缩,并在文件名后实际附加一个版本号,这样我们就可以更轻松地单独控制它们。
2021-03-24 16:17:08
如果您想 10000% 确定,我同意将版本号放在文件名中是最终最安全的解决方案,但我不遵循“同时存在多个版本”的论点。具有查询参数的 URL 与具有不同查询参数的同一 URL 不同。客户端应该将它们视为两种不同的资源;如果不是,则客户端已损坏。
2021-04-07 16:17:08

正如其他人所说,使用查询参数进行缓存破坏通常被认为是一个坏主意 (tm),并且已经存在很长时间了。最好在文件名中反映版本。Html5 Boilerplate建议不要使用查询字符串等。

也就是说,在我所看到的引用来源的建议中,似乎都从Steve Souders 2008 年的一篇文章中汲取了智慧他的结论是基于当时代理人的行为,这些天它们可能相关,也可能不相关。尽管如此,在没有更多最新信息的情况下,更改文件名是安全的选择。

它将破坏缓存一次,在客户端下载资源后,每个其他响应都将从客户端缓存提供,除非:

  1. v 参数被更新。
  2. 客户端清除他们的缓存