当我看到许多站点的源代码时,参数被传递到链接文件(CSS/JavaScript)。
在 Stack Overflow 源代码中,我得到了
<script type="text/javascript" src="http://sstatic.net/js/master.js?v=55c7eccb8e19"></script>
为什么master.js?v=55c7eccb8e19
使用?
我确定 JavaScript/CSS 文件无法获取参数。
是什么原因?
当我看到许多站点的源代码时,参数被传递到链接文件(CSS/JavaScript)。
在 Stack Overflow 源代码中,我得到了
<script type="text/javascript" src="http://sstatic.net/js/master.js?v=55c7eccb8e19"></script>
为什么master.js?v=55c7eccb8e19
使用?
我确定 JavaScript/CSS 文件无法获取参数。
是什么原因?
通常这样做是为了防止缓存。
假设您部署了新应用程序的第 2 版,并且希望使客户端刷新其 CSS,您可以添加此额外参数以指示它应该从服务器重新请求它。当然还有其他方法,但这很简单。
正如其他人所说,这可能是为了控制缓存,尽管我认为最好通过更改实际资源名称 ( foo.v2.js
, not foo.js?v=2
) 而不是查询字符串中的版本来实现。(这并不意味着您必须重命名文件,有更好的方法可以将该 URL 映射到底层文件。)尽管这篇文章已有四年历史,因此在网络世界中很古老,但仍然是一个非常有用的讨论。在其中,作者声称您不想对版本使用查询字符串,因为:
......根据HTTP缓存规格的信,用户端应该永远不会缓存网址查询字符串。虽然 Internet Explorer 和 Firefox 忽略了这一点,但 Opera 和 Safari 不会……
这种说法可能不太正确,因为规范实际上说的是
...由于某些应用程序传统上使用带有查询 URL 的 GET 和 HEAD(在 rel_path 部分中包含“?”的那些)来执行具有显着副作用的操作,缓存不得将此类 URI 的响应视为新鲜的,除非服务器提供明确的到期时间...
(最后的重点是我的。)所以在查询字符串中使用一个版本可能没问题,只要您还包括显式缓存标头。提供的浏览器正确实现了上述内容。代理可以。您明白为什么我认为您最好使用实际资源定位器中的版本,而不是查询参数(这 [再次]并不意味着您必须不断重命名文件;有关更多信息,请参阅上面链接的文章)。您知道,如果您更改名称,沿途的浏览器、代理等将获取更新的资源,这意味着您可以为之前的“名称”提供一个永无止境的缓存时间,以最大限度地发挥中间缓存的优势。
关于:
我确定Js/CSS文件无法获取参数。
仅仅因为返回的结果是 JavaScript 或 CSS 资源,并不意味着它是服务器文件系统上的文字文件。服务器很可能会根据查询字符串参数进行处理并生成自定义的 JavaScript 或 CSS 响应。我没有理由不能将我的服务器配置为将所有.js
文件路由到(比如)一个 PHP 处理程序,该处理程序查看查询字符串并返回一些自定义的内容以匹配给定的字段。因此,如果我已经设置我的服务器来这样做,foo.js?v=2
可能会有所不同foo.js?v=1
。
这是为了避免浏览器缓存文件。附加的版本名称对 JavaScript 文件没有影响,但对于浏览器的缓存引擎来说,它现在看起来像是一个独特的文件。
例如,如果您有scripts.js
浏览器访问该页面,它们会下载并缓存(存储)该文件以加快下一个页面的访问速度。但是,如果您进行更改,浏览器可能无法识别它,直到缓存过期。但是,scripts.js?v2
现在使浏览器强制重新获取,因为“名称已更改”(即使没有更改,但内容已更改)。
生成 CSS 或 JavaScript 代码的服务器端脚本可以使用它们,但它可能只是用于在文件内容更改时更改 URI,以便旧的缓存版本不会引起问题。
<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>