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

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

  1. 在链接和脚本标签中向 CSS 和 JavaScript URL 追加 "?v=1"有什么作用?
  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 -->
131200 次浏览

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

之后,如果你有一个更新的版本和 "?v=3", "?v=4"等等,你可以附加 "?v=2"

请注意,你可以使用任何 querystring,“ v”不是必须的,例如:

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

还有

"?xyz=1002"会起作用的。

这是一种常见的技术,因为浏览器现在缓存 js 和 css 文件的效果越来越好,时间也越来越长。

这些通常是为了确保浏览器获得一个新的版本时,网站得到更新的新版本,例如,作为我们的构建过程的一部分,我们会有这样的东西:

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

由于这种情况随着每次新代码推送而改变,因此客户机不得不获取一个新版本,这仅仅是因为使用了 query 字符串。看看这个页面(在回答这个问题的时候) ,例如:

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

我认为 SO 团队使用文件散列代替了修订号,这是一种更好的方法,即使有了新版本,浏览器也只是在文件 事实上发生变化时才强制获取一个新版本。

这两种方法都允许您将缓存头设置为长得离谱的长度,比如20年... ... 然而,当它发生变化时,您不必担心缓存头,浏览器会看到一个不同的查询字符串,并将其视为一个不同的新文件。

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

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

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

散列解决方案很好,但是当你想知道本地 web 文件夹中的文件是什么版本时,它不是真正的人类可读的。解决方案是使用 date/time标记您的版本,这样您就可以轻松地将它与服务器文件进行比较。

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

应该很容易读取任何语言的任何文件的属性。

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

因为首先要把它很好地重构成属性/函数,然后就可以开始了。

祝你好运,阿特。

为了回答你的问题;

”?V = 1” 这样写只是因为要下载一个新的 css 和 js 文件副本,而不是从浏览器的缓存中使用。

如果您在样式表或 js 文件的末尾提到这个查询字符串参数,那么它将强制浏览器下载一个新文件。CSS 和。Js 文件在您的浏览器中是有效的。

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

这里有一篇文章,解释这件事 如何以及为什么要对 CSS 和 JS 文件进行版本控制

在新版本的开发/测试过程中,缓存可能是一个问题,因为浏览器、服务器,甚至有时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);
}

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

有一个 吞下去插件可以在构建阶段处理文件的版本,所以不需要手动完成。它很方便,您可以很容易地将它集成到您的构建过程中。这是链接: 吞咽注释

正如其他人所提到的,这用于前端缓存崩溃。为了实现这一点,我个人发现 grunt-cache-bustnpm 包很有用。