据我所知,一个常见的解决方案是在脚本的src链接中添加?<version>
。
例如:
<script type="text/javascript" src="myfile.js?1500"></script>
我假设现在没有比查找替换更好的方法来递增所有脚本标签中的“版本号”?你可以使用版本控制系统来完成这项工作。大多数版本控制系统都有自动注入修订号的方式,例如在提交时。它会类似于这样:<script type="text/javascript" src="myfile.js?$$REVISION$$"></script>
当然,总会有更好的解决方案,比如这个。
foo.js?1
和 foo.js?2
不是相同的文件名,因此浏览器会认为它们是两个不同的文件。其中一个缺点是两个文件将同时存在于用户的缓存中,占用不必要的空间。 - Lee White在URL末尾追加当前时间是一种常见的解决方法。但是,如果您想要的话,也可以在Web服务器级别上进行管理。服务器可以配置为为javascript文件发送不同的HTTP标题。
例如,要强制使文件缓存不超过1天,您可以发送:
Cache-Control: max-age=86400, must-revalidate
如果您想强制用户始终获取最新版本的 Beta 版本,则可以使用以下命令:
Cache-Control: no-cache, must-revalidate
Google Page-Speed: 静态资源的 URL 中不应包含查询字符串。 大多数代理服务器(尤其是 Squid 版本 3.0 及以下)即使响应头中有 Cache-control: public 标头,也不会缓存带有“?”的 URL 资源。为了让代理服务器缓存这些资源,请从静态资源的引用中删除查询字符串,并将参数编码到文件名中。
在这种情况下,您可以将版本号包含在 URL 中,例如:v1.2/script.js,并使用 Apache mod_rewrite 将链接重定向到 http://abc.com/script.js。当更改版本时,客户端浏览器将更新新文件。
加入文件大小作为加载参数怎么样?
<script type='text/javascript' src='path/to/file/mylibrary.js?filever=<?=filesize('path/to/file/mylibrary.js')?>'></script>
每次更新文件时,“filever”参数都会更改。
如果您更新文件并且更新导致文件大小相同,那么可能性是多少?
hash_file('md5', 'js/main.js')
。 - Fakhamatia这种用法已经被弃用了: https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache
这个答案虽然晚了6年,但我没有在很多地方看到这个答案... HTML5引入了应用程序缓存,用于解决这个问题。我发现我正在编写的新服务器代码会导致保存在人们浏览器中的旧javascript崩溃,因此我想找到一种方法来过期他们的javascript。使用一个类似这样的清单文件:
CACHE MANIFEST
# Aug 14, 2014
/mycode.js
NETWORK:
*
每次您希望用户更新其缓存时,都需要使用新的时间戳生成此文件。值得注意的是,如果添加了此内容,则浏览器将在清单告诉它之前不会重新加载(即使用户刷新页面)。
?<version>
方法要简单得多。 - amosstuff_123.js
代替stuff.js?123
。
我在Apache中使用了mod_redirect
(我想是这个)来将stuff_*.js
重定向到stuff.js
。
.htaccess
代码那就太好了。 - Fizzix现今常见的做法是在文件名中生成内容哈希码,以强制浏览器(特别是IE)重新加载JavaScript文件或CSS文件。
例如:
vendor.a7561fb0e9a071baadb9.js
main.b746e3eb72875af2caa9.js
这通常是由构建工具(例如Webpack)完成的。如果有人正在使用Webpack并想尝试,请参考此处了解更多细节。
对于ASP.NET页面,我正在使用以下内容
BEFORE
<script src="/Scripts/pages/common.js" type="text/javascript"></script>
AFTER (强制重新加载)
<script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>
添加DateTime.Now.Ticks非常有效。
针对ASP.NET,我建议使用下列高级选项(调试/发布模式,版本):
通过以下方式包含Js或Css文件:
<script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>" />
<link rel="stylesheet" type="text/css" href="Css/exampleCss<%=Global.CssPostfix%>" />
在Global.asax中,Global.JsPostfix和Global.CssPostfix是通过以下方式计算的:
protected void Application_Start(object sender, EventArgs e)
{
...
string jsVersion = ConfigurationManager.AppSettings["JsVersion"];
bool updateEveryAppStart = Convert.ToBoolean(ConfigurationManager.AppSettings["UpdateJsEveryAppStart"]);
int buildNumber = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision;
JsPostfix = "";
#if !DEBUG
JsPostfix += ".min";
#endif
JsPostfix += ".js?" + jsVersion + "_" + buildNumber;
if (updateEveryAppStart)
{
Random rand = new Random();
JsPosfix += "_" + rand.Next();
}
...
}
<script src="https://thesaasdomain.com/somejsfile.js" data-ut="user_token"></script>
if($('script[src^="https://thesaasdomain.com/somejsfile.js?"]').length !== 0) {
init();
} else {
loadScript("https://thesaasdomain.com/somejsfile.js?" + guid());
}
var loadscript = function(scriptURL) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scriptURL;
head.appendChild(script);
}
var guid = function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
var init = function() {
// our main code
}
解释:
用户已在其网站上附加了所提供的脚本,我们使用jQuery选择器检查所附带的唯一标记是否存在,如果不存在,则使用较新的令牌(或版本)动态加载它。
这样做会导致同一个脚本被调用两次,可能会影响性能,但它确实解决了强制脚本不从缓存中加载而不将版本放入实际脚本链接给用户或客户端的问题。
免责声明:如果性能对您很重要,请勿使用此方法。