如何强制客户端刷新JavaScript文件?
我们目前正在进行一个私有测试,因此仍在进行相当快速的更改,尽管很明显,随着使用量的增加,我们将放缓这一过程。话虽如此,我们遇到的一个问题是,在我们推出新JavaScript文件的更新后,客户端浏览器仍然使用该文件的缓存版本,并且看不到更新。显然,在支持电话中,我们可以简单地通知他们进行ctrlF5刷新,以确保他们从服务器获得最新的文件,但最好在此之前处理 我们目前的想法是简单地在JavaScript文件的名称上附加一个版本号,然后在进行更改时,在脚本上增加版本并更新所有引用。这确实完成了任务,但是更新每个版本上的引用可能会很麻烦如何强制客户端刷新JavaScript文件?,javascript,caching,versioning,Javascript,Caching,Versioning,我们目前正在进行一个私有测试,因此仍在进行相当快速的更改,尽管很明显,随着使用量的增加,我们将放缓这一过程。话虽如此,我们遇到的一个问题是,在我们推出新JavaScript文件的更新后,客户端浏览器仍然使用该文件的缓存版本,并且看不到更新。显然,在支持电话中,我们可以简单地通知他们进行ctrlF5刷新,以确保他们从服务器获得最新的文件,但最好在此之前处理 我们目前的想法是简单地在JavaScript文件的名称上附加一个版本号,然后在进行更改时,在脚本上增加版本并更新所有引用。这确实完成了任务,但
因为我确信我们不是第一个处理这个问题的人,我想我会把它扔给社区。当您更新代码时,如何确保客户端更新其缓存?如果使用上述方法,是否使用简化更改的过程?据我所知,常见的解决方案是向脚本的src链接添加
?
例如:
<script type="text/javascript" src="myfile.js?1500"></script>
我假设在这一点上,没有比查找替换更好的方法来增加所有脚本标记中的这些“版本号”了 你可能有一个版本控制系统为你做这件事?例如,大多数版本控制系统都有一种在签入时自动插入修订号的方法 它看起来像这样:
<script type="text/javascript" src="myfile.js?$$REVISION$$"></script>
CACHE MANIFEST
# Aug 14, 2014
/mycode.js
NETWORK:
*
当然,总会有更好的解决方案,比如。据我所知,一个常见的解决方案是在脚本的src链接中添加一个
?
例如:
<script type="text/javascript" src="myfile.js?1500"></script>
我假设在这一点上,没有比查找替换更好的方法来增加所有脚本标记中的这些“版本号”了 你可能有一个版本控制系统为你做这件事?例如,大多数版本控制系统都有一种在签入时自动插入修订号的方法 它看起来像这样:
<script type="text/javascript" src="myfile.js?$$REVISION$$"></script>
CACHE MANIFEST
# Aug 14, 2014
/mycode.js
NETWORK:
*
当然,总会有更好的解决方案,比如。我的同事在我发布(关于css)之后,就发现了一个对该方法的引用。很高兴看到其他人正在使用它,而且它似乎很有效。我假设在这一点上,没有比查找替换更好的方法来增加所有脚本标记中的这些“版本号”?我的同事刚刚在我发布(关于css)之后找到了对该方法的引用。很高兴看到其他人正在使用它,而且它似乎很有效。此时,我假设没有比查找替换更好的方法来增加所有脚本标记中的这些“版本号”一个解决方案是在获取资源时将带有时间戳的查询字符串附加到URL。这利用了浏览器不会缓存从包含查询字符串的URL获取的资源这一事实 您可能根本不希望浏览器不缓存这些资源;更可能的情况是,您希望缓存这些文件,但希望浏览器在文件可用时获取文件的新版本
最常见的解决方案似乎是在文件名本身中嵌入时间戳或修订号。这需要做更多的工作,因为您的代码需要修改以请求正确的文件,但这意味着,例如,
snazzy_javascript_file.js
(即snazzy_javascript_file_7.js
)的第7版将缓存在浏览器上,直到您发布第8版,然后您的代码改为获取snazzy_javascript_file_8.js
。一种解决方案是在获取资源时将带有时间戳的查询字符串附加到URL。这利用了浏览器不会缓存从包含查询字符串的URL获取的资源这一事实
您可能根本不希望浏览器不缓存这些资源;更可能的情况是,您希望缓存这些文件,但希望浏览器在文件可用时获取文件的新版本
最常见的解决方案似乎是在文件名本身中嵌入时间戳或修订号。这需要做更多的工作,因为您的代码需要修改以请求正确的文件,但这意味着,例如,
snazzy_javascript_file.js
(即snazzy_javascript_file_7.js
)的第7版将缓存在浏览器上,直到您发布第8版,然后,您的代码将改为获取时髦的javascript文件8.js。最简单的解决方案?根本不要让浏览器缓存。将当前时间(毫秒)追加为查询
(您仍处于测试阶段,因此您可以提出合理的理由不进行性能优化。但这里是YMMV。)最简单的解决方案?根本不要让浏览器缓存。将当前时间(毫秒)追加为查询
(您仍处于测试阶段,因此您可以合理地说明不进行性能优化的理由。但这里是YMMV。)如果您正在生成链接到JS文件的页面,一个简单的解决方案是将文件的最后修改时间戳附加到生成的链接上
这与Huppie的答案非常相似,但在没有关键字替换的版本控制系统中有效。它也比追加当前时间好,因为即使文件根本没有更改,也会阻止缓存。如果要生成链接到JS文件的页面,一个简单的解决方案是将文件的上次修改时间戳追加到生成的链接上 这与Huppie的答案非常相似,但在没有关键字替换的版本控制系统中有效。它也比附加当前tim更好
<script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>" />
<link rel="stylesheet" type="text/css" href="Css/exampleCss<%=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="/Scripts/pages/common.js" type="text/javascript"></script>
<script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>
CACHE MANIFEST
# Aug 14, 2014
/mycode.js
NETWORK:
*
$(document).ready(function(){
$.getScript("../data/playlist.js", function(data, textStatus, jqxhr){
startProgram();
});
});
<script type='text/javascript' src='path/to/file/mylibrary.js?filever=<?=filesize('path/to/file/mylibrary.js')?>'></script>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.(jpe?g|bmp|png|gif|css|js|mp3|ogg)$ [NC]
RewriteCond %{QUERY_STRING} !^(.+?&v33|)v=33[^&]*(?:&(.*)|)$ [NC]
RewriteRule ^ %{REQUEST_URI}?v=33 [R=301,L]
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true"/>
<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
}
<script src="~/JsFilePath/JsFile.js?v=@DateTime.UtcNow.ToString()"></script>
<head>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0" />
<meta http-equiv="cache-control" content="max-age=0" />
<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" />
</head>
https://www.example.com/script_fv25.js
RewriteEngine On
RewriteRule (.*)_fv\d+\.(js|css|txt|jpe?g|png|svg|ico|gif) $1.$2 [L]
https://www.example.com/script.js
new Date().getTime()
// cache-expires-after.js v1
function cacheExpiresAfter(delay = 1, prefix = '', suffix = '') { // seconds
let now = new Date().getTime().toString();
now = now.substring(now.length - 11, 10); // remove decades and milliseconds
now = parseInt(now / delay).toString();
return prefix + now + suffix;
};
// examples (of the delay argument):
// the value changes every 1 second
var cache = cacheExpiresAfter(1);
// see the sync
setInterval(function(){
console.log(cacheExpiresAfter(1), new Date().getSeconds() + 's');
}, 1000);
// the value changes every 1 minute
var cache = cacheExpiresAfter(60);
// see the sync
setInterval(function(){
console.log(cacheExpiresAfter(60), new Date().getMinutes() + 'm:' + new Date().getSeconds() + 's');
}, 1000);
// the value changes every 5 minutes
var cache = cacheExpiresAfter(60 * 5); // OR 300
// the value changes every 1 hour
var cache = cacheExpiresAfter(60 * 60); // OR 3600
// the value changes every 3 hours
var cache = cacheExpiresAfter(60 * 60 * 3); // OR 10800
// the value changes every 1 day
var cache = cacheExpiresAfter(60 * 60 * 24); // OR 86400
// usage example:
let head = (document.head || document.getElementsByTagName('head')[0]);
let script = document.createElement('script');
script.setAttribute('src', '//unpkg.com/sweetalert@2.1.2/dist/sweetalert.min.js' + cacheExpiresAfter(60 * 5, '?'));
head.append(script);
// this works?
let waitSwal = setInterval(function() {
if (window.swal) {
clearInterval(waitSwal);
swal('Script successfully injected', script.outerHTML);
};
}, 100);
<h1 id="welcome"> Welcome to this page <span style="color:red">... press Ctrl-F5</span></h1>
document.getElementById("welcome").innerHTML = "Welcome to this page"
$fileVersion = rand();
<script src="addNewStudent.js?v=<?php echo $fileVersion; ?>"></script>