如何以编程方式清空浏览器缓存?

Posted

技术标签:

【中文标题】如何以编程方式清空浏览器缓存?【英文标题】:How to programmatically empty browser cache? 【发布时间】:2011-12-30 14:27:14 【问题描述】:

我正在寻找一种以编程方式清空浏览器缓存的方法。我这样做是因为应用程序缓存了机密数据,我想在您按“注销”时删除这些数据。这将通过服务器或 javascript 发生。当然,仍然不鼓励在外国/公共计算机上使用该软件,因为还有更多的危险,例如您无法在软件级别上击败的键盘记录器。

【问题讨论】:

哪些浏览器?您还应该考虑告诉浏览器不要从服务器缓存哪些内容与尝试删除它。 您可能还想查看有关缓存及其工作原理的本教程。 mnot.net/cache_docs 涵盖了缓存控制头和类似的东西 @MechSoftware 我想缓存以加快页面加载速度,但我想在注销后清除它。最好提供尽可能好的浏览器支持。 @rFactor 没有人会使用可以让网站控制其缓存的浏览器。 事实上的网站可以控制缓存,因为它们控制着 HTTP 标头。 【参考方案1】:

不可能浏览器会让您清除其缓存。如果可能的话,这将是一个巨大的安全问题。这很容易被滥用——浏览器支持这种“功能”的那一刻就是我从我的计算机上卸载它的那一刻。

可以做的是告诉它不要缓存你的页面,通过发送适当的标题或使用这些元标记:

<meta http-equiv='cache-control' content='no-cache'>
<meta http-equiv='expires' content='0'>
<meta http-equiv='pragma' content='no-cache'>

您可能还想考虑关闭表单字段的自动完成功能,但恐怕有一种标准方法可以做到这一点 (see this question)。

无论如何,我想指出,如果您正在处理敏感数据,您应该使用 SSL。如果您没有使用 SSL,任何有权访问网络的人都可以嗅探网络流量并轻松查看您的用户所看到的内容。

使用 SSL 还会使某些浏览器使用缓存,除非明确告知。见this question。

【讨论】:

为什么我要清除我的网络应用程序的缓存来惹恼我的用户?我想这样做以清除缓存的私人数据的痕迹。如果我告诉浏览器不要缓存,它必须在每次页面加载时请求数兆字节的客户端数据,这不是我想要做的。 没有人会,因为显然这是不可能的。就像你不能在另一个源上运行脚本并不意味着你不能在你的源上运行脚本。如果您无法清除远程源上的缓存,那是合乎逻辑的,但是为什么我不能清除正在执行代码的源的缓存呢?没有理由不这样做,所以我正在寻找是否有解决方案,但看起来这是不可能的。如果你很好奇,我可以告诉你,我有一个大型应用程序,其中包含大量的 CSS、html 和 JS,编译到大约 6 MB。 @rFactor 这太多了。 请解释一下,无论实施如何,这都会是一个安全问题?这可以安全地实施。 也许我昨晚没睡够,当网络应用程序可以清除(not alter)缓存时,这会是什么安全问题?你怎么能利用它?【参考方案2】:

有可能,你可以简单地使用 jQuery 将引用缓存状态的“元标记”替换为事件处理程序/按钮,然后刷新,简单,

$('.button').click(function() 
    $.ajax(
        url: "",
        context: document.body,
        success: function(s,x)

            $('html[manifest=saveappoffline.appcache]').attr('content', '');
                $(this).html(s);
        
    ); 
);

注意:此解决方案依赖于作为 HTML 5 规范的一部分实施的应用程序缓存。它还需要服务器配置来设置应用缓存清单。它没有描述一种可以通过客户端或服务器端代码清除“传统”浏览器缓存的方法,这几乎是不可能的。

【讨论】:

这只是 HTML5 功能吗? 我会这么说,而且我相信它也需要服务器配置(设置应用程序缓存清单)。虽然这个答案为原始问题提供了一个解决方案,但它掩盖了一个事实,即通过客户端或服务器端代码清除传统的浏览器缓存几乎是不可能的。 这个方法看似绕过缓存更新内容,但是当页面重新加载时,又回到了之前缓存的内容。 已弃用,有利于服务人员 developer.mozilla.org/en-US/docs/Web/HTML/… 服务工作者不能在 iPhone 上工作,所以你必须使用那里的应用缓存【参考方案3】:

使用html本身。有一个技巧可以使用。技巧是在脚本标记中的文件名中附加一个参数/字符串,并在文件更改时更改它。

&lt;script src="myfile.js?version=1.0.0"&gt;&lt;/script&gt;

浏览器将整个字符串解释为文件路径,即使“?”后面是什么。是参数。所以现在发生的事情是,下次更新文件时,只需更改网站上脚本标记中的数字(例如 &lt;script src="myfile.js?version=1.0.1"&gt;&lt;/script&gt;),每个用户的浏览器都会看到文件已更改并获取新副本。

【讨论】:

对于那些使用一些服务器端动态语言的人,如果你可以访问文件的ctime,(或mtime),你可以在后面加上所说的时间。例如,在 php 中,myfile.js?v=&lt;?=filectime('myfile.js');?&gt;,您就可以为自己的资源自动更新缓存。 我已经使用这种技术很多天了。但是我今天注意到,即使在我更改了版本部分之后,该文件仍在从缓存中呈现。我正在使用 Chrome。即使我从服务器上删除了文件,它也显示出来了。任何人都知道为什么它可能不起作用? 这个技巧有效,***.com/questions/1922910/… 这就是我从 2002 年以来一直这样做的方式。它可能很难看,但它一直有效。如果没有全新的 HTML 5.0 功能,我认为这是能够缓存页面并选择何时获取新副本的唯一方法(即:破坏缓存)。【参考方案4】:

最好的办法是生成带有名称的js文件+带有版本的哈希,如果确实需要清除缓存,只需生成带有新哈希的新文件,这将触发浏览器加载新文件

【讨论】:

【参考方案5】:

最初我在我的 html、JS 中尝试了各种编程方法来清除浏览器缓存。在最新的 Chrome 上没有任何效果。

最后,我得到了 .htaccess:

<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>

在 Chrome、Firefox、Opera 中测试

参考:https://wp-mix.com/disable-caching-htaccess/

【讨论】:

这是最好的解决办法。【参考方案6】:

这里是如何使用Cache.delete()删除所有浏览器网络缓存的单行代码

caches.keys().then((keyList) => Promise.all(keyList.map((key) => caches.delete(key))))

适用于 Chrome 40+、Firefox 39+、Opera 27+ 和 Edge。

【讨论】:

这仅适用于脚本(通常在 Service Worker 中)使用缓存 API 显式存储的项目。它不允许访问浏览器的 HTTP(s) 缓存。【参考方案7】:

在 Chrome 上,您应该可以使用基准测试扩展程序执行此操作。您需要使用以下开关启动 chrome:

./chrome --enable-benchmarking --enable-net-benchmarking 

现在您可以在 Chrome 的控制台中执行以下操作:

chrome.benchmarking.clearCache();
chrome.benchmarking.clearHostResolverCache();
chrome.benchmarking.clearPredictorCache();
chrome.benchmarking.closeConnections();

从上面的命令可以看出,它不仅会清除浏览器缓存,还会清除 DNS 缓存并关闭网络连接。当您进行页面加载时间基准测试时,这些非常有用。显然,如果不需要,您不必全部使用它们(例如,如果您只需要清除缓存并且不关心 DNS 缓存和连接,则 clearCache() 就足够了)。

【讨论】:

【参考方案8】:

location.reload(true);将硬重新加载当前页面,忽略缓存。 Cache.delete()也可以用于新的chrome、firefox和opera。

【讨论】:

此功能不适用于 Internet Explorer 和 safari 浏览器。不确定是否适用于 Microsoft Edge。【参考方案9】:

您现在可以使用Cache.delete()

例子:

let id = "your-cache-id";
// you can find the id by going to 
// application>storage>cache storage 
// (minus the page url at the end)
// in your chrome developer console 

caches.open(id)
.then(cache => cache.keys()
  .then(keys => 
    for (let key of keys) 
      cache.delete(key)
    
  ));

适用于 Chrome 40+、Firefox 39+、Opera 27+ 和 Edge。

【讨论】:

最佳答案。完美运行【参考方案10】:

您可以让服务器响应 Clear Site Data 指令,指示用户代理清除站点本地存储的数据。

例如:

Clear-Site-Data: "cache", "cookies", "storage"

该标头将指示用户代理清除所有本地存储的数据,包括:

网络缓存 用户代理缓存(如预渲染页面、脚本缓存等) Cookie HTTP 身份验证凭据 源绑定令牌(例如通道 ID 和令牌绑定) 本地存储 会话存储 索引数据库 Web SQL 数据库 Service Worker 注册

您可以使用fetch() 发送请求,然后使用location.reload() 重新启动。

【讨论】:

【参考方案11】:

//The code below should be put in the "js" folder with the name "clear-browser-cache.js"

(function () 
    var process_scripts = false;
    var rep = /.*\?.*/,
    links = document.getElementsByTagName('link'),
    scripts = document.getElementsByTagName('script');
    var value = document.getElementsByName('clear-browser-cache');
    for (var i = 0; i < value.length; i++) 
        var val = value[i],
            outerHTML = val.outerHTML;
        var check = /.*value="true".*/;
        if (check.test(outerHTML)) 
            process_scripts = true;
        
    
    for (var i = 0; i < links.length; i++) 
        var link = links[i],
        href = link.href;
        if (rep.test(href)) 
            link.href = href + '&' + Date.now();
        
        else 
            link.href = href + '?' + Date.now();
        
    
    if (process_scripts) 
        for (var i = 0; i < scripts.length; i++) 
            var script = scripts[i],
            src = script.src;
            if (src !== "") 
                if (rep.test(src)) 
                    script.src = src + '&' + Date.now();
                
                else 
                    script.src = src + '?' + Date.now();
                
            
        
    
)();
At the end of the tah head, place the line at the code below

    < script name="clear-browser-cache" src='js/clear-browser-cache.js' value="true" >< /script >

【讨论】:

目前还不清楚这个答案是如何工作的,以及它如何比许多现有的答案更好。通过描述您所遵循的方法以及说明为什么会起作用的支持文档,可以大大改善这一点 虽然赞赏,但这不会清除浏览器缓存,它似乎只是通过添加参数来缓存给定页面上的任何链接。 只需遍历链接标签和脚本标签的列表,并在它加载的末尾附加查询参数。就这么简单【参考方案12】:

想象.js 文件放在/my-site/some/path/ui/js/myfile.js

所以通常脚本标签看起来像:

<script src="/my-site/some/path/ui/js/myfile.js"></script>

现在改成:

<script src="/my-site/some/path/ui-1111111111/js/myfile.js"></script>

现在这当然行不通。要使其正常工作,您需要在 .htaccess 中添加一行或几行 重要的一行是:(整个 .htaccess 在底部)

RewriteRule ^my-site\/(.*)\/ui\-([0-9]+)\/(.*) my-site/$1/ui/$3 [L]

所以它的作用是从路径中删除1111111111 并链接到正确的路径。

所以现在,如果您进行更改,您只需将号码 1111111111 更改为您想要的任何号码。但是,无论您包含文件,您都可以通过上次修改 js 文件时的时间戳来设置该数字。所以如果数字没有变化,缓存会正常工作。如果它发生变化,它将提供新文件(始终是),因为浏览器获取的是一个完整的新 URL,并且只是认为该文件是如此新,他必须去获取它。

您可以将其用于CSSfavicons 以及任何被缓存的内容。对于 CSS,只需像这样使用

<link href="http://my-domain.com/my-site/some/path/ui-1492513798/css/page.css" type="text/css" rel="stylesheet">

它会起作用的!更新简单,维护简单。

承诺的完整 .htaccess

如果您还没有 .htaccess,这是您需要的最低要求:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    RewriteRule ^my-site\/(.*)\/ui\-([0-9]+)\/(.*) my-site/$1/ui/$3 [L]
</IfModule>

【讨论】:

【参考方案13】:

通过定义缓存无效元标记的函数:

function addMetaTag(name,content)
var meta = document.createElement('meta');
meta.httpEquiv = name;
meta.content = content;
document.getElementsByTagName('head')[0].appendChild(meta);

您可以致电:

addMetaTag("pragma","no-cache")
addMetaTag("expires","0")
addMetaTag("cache-control","no-cache")

这将为后续请求插入元标记,这将迫使浏览器获取新内容。插入后,您可以调用location.reload(),这将适用于大多数浏览器(例如,Cache.delete() 不适用于 chrome。)

【讨论】:

以上是关于如何以编程方式清空浏览器缓存?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式清除缓存?

以编程方式使 Silverlight XAP 文件从浏览器缓存中过期

wpf中DataGrid如何清空缓存

如何快速清空微信浏览器中的缓存

Asp.Net WEb中怎么清空缓存?

firefox火狐浏览器怎么清理缓存