caching通过params破坏

我们希望在生产部署中caching萧条,但是不要浪费一大堆时间去搞清楚这样做的系统。 我的想法是将当前版本号应用于css和js文件的结尾:

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

两个问题:这会有效地打破caching吗? 这个参数是否会导致浏览器永远不会caching来自该URL的响应,因为param指出这是dynamic内容?

参数?v=1.123表示一个查询string,因此浏览器会认为它是一个新的path,比如说?v=1.0 。 从而导致它从文件加载,而不是从caching中加载。 如你所愿。

而且,浏览器会假定下次你调用的时候,源代码会保持不变, ?v=1.123并且应该用这个stringcaching它。 所以它会保持caching,但是你的服务器是设置的,直到你移动到?v=1.124左右。

两个问题:这会有效地打破caching吗?

是。 即使Stack Overflow也使用这种方法,但我记得他们(每天有数百万的访问者和不同的客户端和代理版本和configuration)已经有一些怪异的边缘情况,即使这样也不足以打破caching。 但一般的假设是,这将起作用,并且是打破客户端caching的合适方法。

这个参数是否会导致浏览器永远不会caching来自该URL的响应,因为param指出这是dynamic内容?

不可以。参数不会改变caching策略。 由服务器发送的caching头仍然适用,如果不发送任何,浏览器的默认值。

将版本号放在实际的文件名中是比较安全的。 这允许同时存在多个版本,因此您可以推出新版本,并且如果任何caching的HTML页面仍然存在请求较旧的版本,他们将获得与其HTML一起工作的版本。

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

当你部署新的页面和新的链接文件(这是你想要的)时,这会破坏一次caching,从那时起,这些版本可以被有效地caching(你也想要)。

在客户端下载了资源后,每隔一个响应将从客户端caching中提供,除非:

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

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

这就是说,我所看到的那些引用来源的build议似乎都是从史蒂夫·苏德斯(Steve Souders) 2008年的一篇文章中获得的。 他的结论是基于当时代理人的行为,而且他们现在可能也可能不相关。 但是,如果没有更多的最新信息,更改文件名是安全的select。

一般来说,这应该没问题,但是如果有一个configuration为忽略请求参数的中间caching(代理),这可能不起作用。

例如,如果您通过Akamai CDN提供静态内容,则可以将其configuration为忽略请求参数,以防止使用此方法caching清除。

它非常依赖于你想要caching的强大程度。 例如,squid代理服务器(可能还有其他服务器) 默认caching使用查询string服务的URL–至less在写文章的时候是这样。 如果您不介意导致不必要的caching未命中的某些用例,请继续查询参数。 但是,build立一个基于文件名的caching清除scheme可以容易地避免这个问题。

在这里find2种技术(查询string与文件名)的比较:

版本作为查询string有两个问题。

首先,它可能并不总是一个实现我们需要破解的caching的浏览器。 据说某些(可能较老的)代理在caching行为方面会忽略查询string。

其次,在某些更复杂的部署场景中,如果您拥有多个前端和/或多个后端服务器,那么升级只能是瞬间的。 您需要能够同时处理资产的旧版本和新版本。 请参阅使用Google App Engine时对您的影响。

另一个类似的方法是使用htaccess mod_rewrite忽略部分path时提供的文件。 从未caching的索引页面引用文件的最新path。

从开发的angular度来看,它就像使用参数的版本号一样简单,但它像文件名的方法一样健壮。

使用path的忽略部分作为版本号,服务器只是忽略它并提供未caching的文件。

1.2.3/css/styles.css提供与1.2.3/css/styles.css相同的文件,因为第一个目录被剥离并被htaccess文件忽略

包括版本文件

 <?php $version = "1.2.3"; ?> <html> <head> <meta http-equiv="cache-control" content="max-age=0" /> <meta http-equiv="cache-control" content="no-cache" /> <meta http-equiv="expires" content="0" /> <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" /> <meta http-equiv="pragma" content="no-cache" /> <link rel="stylesheet" type="text/css" href="<?php echo $version ?>/css/styles.css"> </head> <body> <script src="<?php echo $version ?>/js/main.js"></script> </body> </html> 

请注意,这种方法意味着你需要禁用caching你的索引页 – 使用<meta>标签closures所有浏览器中的caching?

.htaccess文件

 RewriteEngine On # if you're requesting a file that exists, do nothing RewriteCond %{REQUEST_FILENAME} !-f # likewise if a directory that exists, do nothing RewriteCond %{REQUEST_FILENAME} !-d # otherwise, rewrite foo/bar/baz to bar/baz - ignore the first directory RewriteRule ^[^/]+/(.+)$ $1 [L] 

你可以在任何允许url重写的服务器平台上使用同样的方法

(重写条件从mod_rewrite改写 – 重写目录到查询string除了/#!/ )

…如果您需要caching清除您的索引页面/站点入口点,则可以始终使用JavaSript来刷新它。

 <script type="text/javascript"> // front end cache bust var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js']; for (i=0; i < cacheBust.length; i++){ var el = document.createElement('script'); el.src = cacheBust[i]+"?v=" + Math.random(); document.getElementsByTagName('head')[0].appendChild(el); } </script> 

要caching突发,请在URL末尾使用一些随机数,如下所示

 <script type="text/javascript" language="JavaScript"> ord=Math.random()*10000000000000000; </script> 

和浏览器创build这样的事情,

 http://ad.doubleclick.net/ABC/publisher/zone;topic=abc;sbtpc=def;cat=ghi;kw=xyz;tile=1;slot=728x90.1;sz=728x90;ord=7268140825331981? 

更多细节在这里 。