清除JavaScript中的缓存

如何用JavaScript清除浏览器缓存?

我们部署了最新的JavaScript代码,但是我们无法获得最新的JavaScript代码。

编者按:这个问题在以下几个地方有半重复,下面第一个问题的答案可能是最好的。这个公认的答案不再是理想的解决方案。

如何强制浏览器重新加载缓存的CSS/JS文件?< / >

如何强制客户端刷新JavaScript文件?

动态重载本地Javascript源/ json数据

618034 次浏览
javascript不能清除缓存。 一种常见的方法是将修订号或最近一次更新的时间戳附加到文件中,例如:

myscript.123.js

myscript.js?updated=1234567890

尝试更改JavaScript文件的src?从这个:

<script language="JavaScript" src="js/myscript.js"></script>

:

<script language="JavaScript" src="js/myscript.js?n=1"></script>

这个方法应该强制浏览器加载JS文件的新副本。

我倾向于对框架进行版本化,然后将版本号应用于脚本和样式路径

<cfset fw.version = '001' />
<script src="/scripts/#fw.version#/foo.js"/>

在PHP中,你也可以强制每小时重新加载一次代码,就像这样:

<?php
echo '<script language="JavaScript" src="js/myscript.js?token='.date('YmdH').'">';
?>

<script type="text/javascript" src="js/myscript.js?v=<?php echo date('YmdHis'); ?>"></script>

这是我在我的最新项目中使用的一个片段。

来自控制器:

if ( IS_DEV ) {
$this->view->cacheBust = microtime(true);
} else {
$this->view->cacheBust = file_exists($versionFile)
// The version file exists, encode it
? urlencode( file_get_contents($versionFile) )
// Use today's year and week number to still have caching and busting
: date("YW");
}

从视图来看:

<script type="text/javascript" src="/javascript/somefile.js?v=<?= $this->cacheBust; ?>"></script>
<link rel="stylesheet" type="text/css" href="/css/layout.css?v=<?= $this->cacheBust; ?>">

我们的发布过程生成一个包含当前版本版本号的文件。这是通过URL编码文件,并使用它作为缓存破坏者。作为故障转移,如果该文件不存在,则使用年和周数,以便缓存仍能工作,并且至少每周刷新一次。

此外,这为开发环境中的每个页面加载提供了缓存破坏,这样开发人员就不必担心为任何资源(javascript、css、ajax调用等)清除缓存。

更新:参见Location.reload()没有参数了解这个非标准参数的背景知识,以及Firefox如何成为唯一支持该参数的现代浏览器。


你可以调用window.location.reload(真正的)来重新加载当前页面。它将忽略任何缓存项,并从服务器检索页面、css、图像、JavaScript等的新副本。这不会清除整个缓存,但会清除您所在页面的缓存。

但是,最好的策略是对路径或文件名进行版本控制,就像在其他各种答案中提到的那样。此外,请参阅旋转文件名:不要使用querystring了解不使用?v=n作为版本控制方案的原因。

把这个放在模板的末尾:

var scripts =  document.getElementsByTagName('script');
var torefreshs = ['myscript.js', 'myscript2.js'] ; // list of js to be refresh
var key = 1; // change this key every time you want force a refresh
for(var i=0;i<scripts.length;i++){
for(var j=0;j<torefreshs.length;j++){
if(scripts[i].src && (scripts[i].src.indexOf(torefreshs[j]) > -1)){
new_src = scripts[i].src.replace(torefreshs[j],torefreshs[j] + 'k=' + key );
scripts[i].src = new_src; // change src in order to refresh js
}
}
}

或者你可以通过服务器用file_get_contts读取js文件,然后在js内容的头中放入echo

除了每小时或每周缓存一次之外,您还可以根据文件数据进行缓存。

示例(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>

我有一些问题与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/myscript.js?rev=<?php echo time();?>"
type="text/javascript"></script>

试试这个

 <script language="JavaScript" src="js/myscript.js"></script>

:

 <script language="JavaScript" src="js/myscript.js?n=1"></script>
window.parent.caches.delete("call")

在控制台中执行代码后,关闭并打开浏览器。

Cache.delete ()可以用于新的chrome, firefox和opera。

也许“清除缓存”并不像应该的那样简单。而不是在我的浏览器上清除缓存,我意识到“触摸”文件实际上会改变缓存在服务器上的源文件的日期(在Edge, Chrome和Firefox上测试),大多数浏览器会自动下载你服务器上的最新副本(代码,图形任何多媒体)。我建议你在程序运行之前复制服务器上最新的脚本和"触摸事物"解决方案,这样它就会将所有问题文件的日期更改为最新的日期和时间,然后它会下载一个新的副本到你的浏览器:

<?php
touch('/www/control/file1.js');
touch('/www/control/file2.js');
touch('/www/control/file2.js');
?>

...剩下的程序…

我花了一些时间来解决这个问题(因为许多浏览器对不同的命令有不同的行为,但它们都检查文件的时间,并将其与浏览器中下载的副本进行比较,如果日期和时间不同,将进行刷新),如果你不能按照假设的正确方式进行,总有另一种可用的更好的解决方案。祝你露营愉快。

请不要提供错误的信息。 缓存apihttp缓存

是不同类型的缓存

当服务器发送正确的时,会触发HTTP缓存,你不能用javasvipt访问。

另一方面,缓存api在你想要的时候被触发,它在使用服务人员时很有用,所以你可以从这种类型的缓存中交叉请求和回答它 参见:预展1 预展2 课程

你可以使用这些技巧让你的用户总是有新鲜的内容:

  1. 使用location.reload(真正的)这对我不适用,所以我不推荐它。
  2. 使用缓存api来保存到缓存中并与 请求服务人员,小心这个,因为 如果服务器已经为你想要的文件发送了缓存头 要刷新,浏览器将首先从HTTP缓存中应答,如果它没有找到它,那么它将转到网络,因此您可能最终得到一个旧文件
  3. 从你的静态文件中更改url,我的建议是你应该根据文件内容的变化来命名它,我使用md5,然后将其转换为字符串和url友好型,md5将随着文件的内容而改变,在那里你可以自由地发送HTTP缓存头足够长的时间

我推荐第三个看到

你也可以用元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/ < / p >

或者你可以像这样创建一个按钮

<button type="button" onclick="location.reload(true)">Refresh</button>

它会刷新并避免缓存,但它会在你的页面上,直到你完成测试,然后你可以把它拿掉。第一个选择是最好的选择。

因为浏览器缓存相同的链接,你应该添加一个随机数结束的url。 new Date(). gettime ()生成不同的数字

只需添加new Date().getTime()链接结束如 叫< / p >

'https://stackoverflow.com/questions.php?' + new Date().getTime()

输出:https://stackoverflow.com/questions.php?1571737901173

window.location.reload(true)似乎已经被HTML5标准弃用了。不使用查询字符串的一种方法是使用Clear-Site-Data,它似乎是被标准化

我已经通过使用解决了这个问题 ETag < / p >

Etag类似于指纹,如果给定URL上的资源发生变化,则必须生成一个新的Etag值。比较它们可以确定资源的两个表示是否相同。

裁判: https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete

Cache.delete ()

方法

语法:

cache.delete(request, {options}).then(function(found) {
// your cache entry has been deleted if found
});

最近我找到了解决这个问题的办法。在我的情况下,我试图更新一个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元素无效。但在这两种技术之间,你可以更新任何你现在需要的信息:-)

大多数正确答案在这个话题中已经提到了。然而,我想添加一篇文章的链接,这是我能读到的最好的一篇文章。

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将为跨源资源保留卡住的对象,但仅用于后续获取。每个浏览器都将使对象的导航缓存无效,无论是同一源资源还是跨源资源。

==============================

我们尝试了很多方法,但是这个很有效。唯一的问题是,你需要能够以某种方式将这个脚本带到最终用户页面,这样你就能够重置缓存。在这种特殊情况下,我们是幸运的。