在链接和脚本标签中的CSS和Javascript URL后面附加“?v = 1”有什么作用?


138

我一直在查看HTML 5样板模板(来自http://html5boilerplate.com/),并注意到"?v=1"在引用CSS和Javascript文件时在URL中的使用。

  1. "?v=1"在链接和脚本标记中附加到CSS和Javascript URL有什么作用?
  2. 并非所有的Javascript URL都有"?v=1"(示例来自以下示例:)js/modernizr-1.5.min.js。有这种原因吗?

来自他们的样本index.html

<!-- CSS : implied media="all" -->
<link rel="stylesheet" href="css/style.css?v=1">

<!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=1">

<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="js/modernizr-1.5.min.js"></script>

<!------ Some lines removed ------>

<script src="js/plugins.js?v=1"></script>
<script src="js/script.js?v=1"></script>

<!--[if lt IE 7 ]>
  <script src="js/dd_belatedpng.js?v=1"></script>
<![endif]-->


<!-- yui profiler and profileviewer - remove for production -->
<script src="js/profiling/yahoo-profiling.min.js?v=1"></script>
<script src="js/profiling/config.js?v=1"></script>
<!-- end profiling code -->

Answers:


175

这些通常是为了确保在网站更新为新版本时浏览器获得新版本,例如,在我们的构建过程中,我们将具有以下内容:

/Resources/Combined.css?v=x.x.x.buildnumber

由于每次输入新代码都会改变这种情况,因此仅由于查询字符串,客户端就不得不获取新版本。例如,查看此页面(在回答此问题时):

<link ... href="http://sstatic.net/stackoverflow/all.css?v=c298c7f8233d">

我认为SO团队可以使用文件哈希来代替修订号,这是一种更好的方法,即使使用了新版本,浏览器也只在文件实际更改时才强制使用新版本。

这两种方法都允许您将缓存标头设置为非常长的时间,例如20年。然而,当它更改时,您不必担心该缓存标头,浏览器会看到不同的查询字符串并将其视为不同的新文件。


3
@Free- 昨天发送的缓存控制标头无法告诉客户端今天更改的文件(客户端甚至不会检查),URL可以。您能解释一下我在那儿想念的吗?
尼克·克拉弗

8
@Free-这些文件的缓存方式是永远的,这意味着客户端绝不会检查文件是否被修改。这意味着他们永远不会获取更新的文件...除非更改了URL,这是上述技术所发生的。您可以在客户端上获得最长的缓存寿命(最少的HTTP请求),但是当文件实际更改时,客户端会立即更新。究竟如何使用缓存控制标头来完成所有这些工作?
尼克·克雷弗

4
@Free -堆栈溢出得到每月500万个访问者,你的做法将有2度的影响:1)许多从我们的服务器发送到/更多的请求和数据,以及b)用户不会立即得到新的JavaScript / CSS(例如当我们遇到错误或HTML更改需要新的JS / CSS时)。自然到期日实际上不是一个选择。您提出的方法从技术上讲效率会低得多,并且会导致实际的用户bug(定期)……在任何主要站点上,这都是不可接受的(实际上也不应该在任何站点上)。
尼克·克拉弗

2
@Free-500万是每月 500万访问者,由于我们每天部署多次,因此请求是该次的许多倍。就HTML页面加载而言,我们每月谈论的数量略超过1.1亿(并且还在不断增长……这仅仅是 HTML页面加载)。对于a)是的,有更多或更多的中断,这是在缓存时间与具有正确内容的客户端之间的一种折衷选择。另外,您对b)的逻辑有缺陷,html 未被缓存,因此与不再起作用的缓存JS一起使用意味着缓存的用户会受到影响,而不是免疫。
尼克·克拉弗

5
@GMsoF v仅代表我们“版本”,这是一个完全任意的选择。任何值查询字符串都可以使用,例如,可以很容易地使用?jejdutogjesudo =
Nick Craver

23

这可以确保您从服务器的css或js文件中获取最新版本。

然后,"?v=2"如果您有较新的版本,则可以追加"?v=3", "?v=4",依此类推。

请注意,您可以使用any querystring,例如,'v'不是必须的:

"?blah=1”也将起作用。

"?xyz=1002" 将工作。

这是一种常见的技术,因为浏览器现在可以更好,更长地缓存js和css文件。


13

当您想知道本地Web文件夹中的文件版本时,哈希解决方案是不错的选择,但并不是真正可读的。解决方案是date/time标记您的版本,以便您可以轻松地将其与服务器文件进行比较。

例如,如果您的.js or .css文件标有日期2011-02-08 15:55:30(最后修改),则版本应等于.js?v=20110208155530

应该易于阅读任何语言的任何文件的属性。在ASP.Net中,这非常容易...

".js?v=" + File.GetLastWriteTime(HttpContext.Current.Request.PhysicalApplicationPath + filename).ToString("yyMMddHHHmmss");

首先,将它很好地重构为属性/函数,然后就可以使用了。别再找借口。

祝你好运,艺术。


2
如果仅使用html js和css构建网站该怎么办。那么我们如何自动将版本名称注入静态资源呢?
Nishanth Nair 2014年

@ Whizkid747的回复较晚,但对于新手,无论您使用的是哪种网站构建器/构建系统,都应有一种方法来获取以毫秒为单位的日期(可以用作版本),否则,如果您未使用构建器//构建系统您必须自己编写这些。
AntK

7

Javascript文件通常被浏览器缓存的时间比您预期的要长得多。

当您发布新版本的JS文件时,这通常可能导致意外行为。

因此,通常的做法是将QueryString参数添加到javascript文件的URL。这样,浏览器将v = 1缓存在Javascript文件中。当您发布新版本的javascript文件时,您将网址更改为v = 2,浏览器将被迫下载新副本。


到底哪个浏览器?即使是最古怪的IE 5和IE 6也都遵循缓存控制标头。
免费咨询,时间

7

为了回答您的问题;

编写 “?v = 1”仅是为了下载css和js文件的新副本,而不是从浏览器的缓存中使用。

如果您在样式表或js文件的末尾提到此查询字符串参数,则它将强制浏览器下载新文件,因此,.css和.js文件中的最新更改在浏览器中生效。

如果不使用此版本控制,则可能需要清除刷新页面的缓存,以查看这些文件中的最新更改。

这是一篇介绍此事的文章,介绍了如何以及为什么对CSS和JS文件进行版本控制


2

在开发/测试新版本期间,缓存可能会成为问题,因为浏览器,服务器甚至3G电信公司(如果您进行移动部署)有时会缓存静态内容(例如JS,CSS,HTML,img)。您可以通过在URL上附加版本号,随机数或时间戳来克服此问题,例如:JSP:<script src="js/excel.js?time=<%=new java.util.Date()%>"></script>

如果您运行的是纯HTML(而不是服务器页面JSP,ASP,PHP),则服务器将无济于事。在浏览器中,链接是在JS运行之前加载的,因此,您必须删除链接并使用JS加载它们。

// 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);
}

0

如您之前所读,请?v=1确保您的浏览器获取文件的版本1。当您拥有一个新版本时,只需添加一个不同的版本号,浏览器就会忘记旧版本并加载新版本。

有一个gulp插件可以在构建阶段处理文件的版本,因此您无需手动进行。它很方便,您可以轻松地将其集成到构建过程中。这是链接:gulp-注释


-2

正如其他人所提到的,这用于前端缓存清除。为此,我个人发现grunt-cache-bust npm软件包很有用。


1
尽管此链接可以回答问题,但在Stack Overflow上不鼓励仅链接的答案,但是您可以通过将链接的重要部分放入答案中来改善此答案,这可以确保如果更改链接,您的答案仍然是答案或删除:)
WhatsThePoint
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.