如何用JavaScript清除浏览器缓存?
我们部署了最新的JavaScript代码,但是我们无法获得最新的JavaScript代码。
编者按:这个问题在以下几个地方有半重复,下面第一个问题的答案可能是最好的。这个公认的答案不再是理想的解决方案。
如何强制浏览器重新加载缓存的CSS/JS文件?
如何强制客户端刷新JavaScript文件?
动态重载本地Javascript源/ json数据
如何用JavaScript清除浏览器缓存?
我们部署了最新的JavaScript代码,但是我们无法获得最新的JavaScript代码。
编者按:这个问题在以下几个地方有半重复,下面第一个问题的答案可能是最好的。这个公认的答案不再是理想的解决方案。
如何强制浏览器重新加载缓存的CSS/JS文件?
如何强制客户端刷新JavaScript文件?
动态重载本地Javascript源/ json数据
当前回答
大多数正确答案在这个话题中已经提到了。然而,我想添加一篇文章的链接,这是我能读到的最好的一篇文章。
https://www.fastly.com/blog/clearing-cache-browser
在我看来,最合适的解决方案是:
POST在一个iframe中。下面是建议帖子的一个小删减:
=============
const ifr = document.createElement('iframe');
ifr.name = ifr.id = 'ifr_'+Date.now();
document.body.appendChild(ifr);
const form = document.createElement('form');
form.method = "POST";
form.target = ifr.name;
form.action = ‘/thing/stuck/in/cache’;
document.body.appendChild(form);
form.submit();
有一些明显的副作用:这将创建一个浏览器历史记录条目,并受到响应未缓存的相同问题的影响。但它逃脱了fetch存在的预飞行要求,并且由于它是一个导航,分割缓存的浏览器将清除正确的缓存。
这个几乎能搞定。Firefox将为跨源资源保留卡住的对象,但仅用于后续获取。每个浏览器都将使对象的导航缓存无效,无论是同一源资源还是跨源资源。
==============================
我们尝试了很多方法,但是这个很有效。唯一的问题是,你需要能够以某种方式将这个脚本带到最终用户页面,这样你就能够重置缓存。在这种特殊情况下,我们是幸运的。
其他回答
我有一些问题与yboussard建议的代码。内j循环不起作用。下面是我成功使用的修改后的代码。
function reloadScripts(toRefreshList/* list of js to be refresh */, key /* change this key every time you want force a refresh */) {
var scripts = document.getElementsByTagName('script');
for(var i = 0; i < scripts.length; i++) {
var aScript = scripts[i];
for(var j = 0; j < toRefreshList.length; j++) {
var toRefresh = toRefreshList[j];
if(aScript.src && (aScript.src.indexOf(toRefresh) > -1)) {
new_src = aScript.src.replace(toRefresh, toRefresh + '?k=' + key);
// console.log('Force refresh on cached script files. From: ' + aScript.src + ' to ' + new_src)
aScript.src = new_src;
}
}
}
}
除了每小时或每周缓存一次之外,您还可以根据文件数据进行缓存。
示例(PHP):
<script src="js/my_script.js?v=<?=md5_file('js/my_script.js')?>"></script>
甚至使用文件修改时间:
<script src="js/my_script.js?v=<?=filemtime('js/my_script.js')?>"></script>
我已经通过使用解决了这个问题 ETag
Etag类似于指纹,如果给定URL上的资源发生变化,则必须生成一个新的Etag值。比较它们可以确定资源的两个表示是否相同。
你也可以用元HTML标签禁用浏览器缓存,只要把HTML标签放在头部部分,以避免网页被缓存,而你正在编码/测试,当你完成时,你可以删除元标签。
(在标题部分)
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0"/>
在头部粘贴后刷新页面,应该也会刷新新的javascript代码。
如果你需要的话,这个链接会给你其他选择 http://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/
或者你可以像这样创建一个按钮
<button type="button" onclick="location.reload(true)">Refresh</button>
它会刷新并避免缓存,但它会在你的页面上,直到你完成测试,然后你可以把它拿掉。第一个选择是最好的选择。
最近我找到了解决这个问题的办法。在我的情况下,我试图更新一个html元素使用javascript;我一直在使用XHR根据从GET请求中检索到的数据更新文本。尽管XHR请求频繁发生,但缓存的HTML数据却令人沮丧地保持不变。
最近,我在fetch api中发现了一个缓存破坏方法。fetch api取代了XHR,使用起来超级简单。这里有一个例子:
async function updateHTMLElement(t) {
let res = await fetch(url, {cache: "no-store"});
if(res.ok){
let myTxt = await res.text();
document.getElementById('myElement').innerHTML = myTxt;
}
}
注意到{cache: "no-store"}参数了吗?这将导致浏览器破坏该元素的缓存,以便正确加载新数据。天哪,这对我来说简直是天赐良机。我希望这对你也有帮助。
稍微讲一下,为了破坏在服务器端更新的图像的缓存,但保持相同的src属性,最简单和最古老的方法是简单地使用Date.now(),并将该数字作为url变量附加到该图像的src属性。这对图像可靠,但对HTML元素无效。但在这两种技术之间,你可以更新任何你现在需要的信息:-)