How to programmatically empty browser cache?
Asked Answered
R

15

171

I am looking for a way to programmatically empty the browser cache. I am doing this because the application caches confidential data and I'd like to remove those when you press "log out". This would happen either via server or JavaScript. Of course, using the software on foreign/public computer is still discouraged as there are more dangers like key loggers that you just can't defeat on software level.

Rysler answered 16/11, 2011 at 16:25 Comment(8)
Which browsers? You should also look at telling the browser what not to cache from the server vs. trying to erase it.Hesketh
You might also want to check out this tutorial on Caching and how it works. mnot.net/cache_docs covers cache control headers and stuff like thatSeverity
@MechSoftware I want to cache for faster page loads, but I want to clear it after log off. Preferably as good browser support as possible.Rysler
@rFactor Nobody would use a browser that gives websites control over its cache.Azov
check this link , it may useful to clear the browser cache #6259052Heurlin
De facto websites have control over the cache, because they control HTTP headers.Riegel
@NullUserException: That is too far reaching a statement imo. Most regular users are happy to give a website control over cookies, localStorage, etc. for the server's domain. So it wouldn't surprise me if most regular users are okay with servers controlling the browser cache for the server's domain.Duomo
2023: Use the Clear-Site-Data header. See answer on a related question.Duomo
K
43

It's possible, you can simply use jQuery to substitute the 'meta tag' that references the cache status with an event handler / button, and then refresh, easy,

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

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

NOTE: This solution relies on the Application Cache that is implemented as part of the HTML 5 spec. It also requires server configuration to set up the App Cache manifest. It does not describe a method by which one can clear the 'traditional' browser cache via client- or server-side code, which is nigh impossible to do.

Kriegspiel answered 8/11, 2012 at 15:11 Comment(5)
Is this only an HTML5 feature?Franck
I would say so, and I believe it also it also requires server configuration (to set up the app cache manifest). While this answer offers a solution to the original question, it obscures the fact that it's nigh impossible to clear the traditional browser cache via client- or server-side code.Psychopath
This method seems to bypass the cache and update the content, but when the page is reloaded, it goes back to the previously cached content.Tieratierce
deprecated in favor of service workers developer.mozilla.org/en-US/docs/Web/HTML/…Specialist
service workers don't work on iPhones so you have to use the app cache thereSelfservice
A
195

2023 update: See the Clear-Site-Data HTTP header, through which the server can instruct a client web browser to clear the website cache for its domain/subdomain, regardless of earlier Cache-Control headers. Intermediate caches may still have the data cached though and may not respect the header. (thanks, @nishanthshanmugham)

There's no way a browser will let you clear its cache. It would be a huge security issue if that were possible. This could be very easily abused - the minute a browser supports such a "feature" will be the minute I uninstall it from my computer.

What you can do is to tell it not to cache your page, by sending the appropriate headers or using these meta tags:

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

You might also want to consider turning off auto-complete on form fields, although I'm afraid there's a standard way to do it (see this question).

Regardless, I would like to point out that if you are working with sensitive data you should be using SSL. If you aren't using SSL, anyone with access to the network can sniff network traffic and easily see what your user is seeing.

Using SSL also makes some browsers not use caching unless explicitly told to. See this question.

Azov answered 16/11, 2011 at 16:29 Comment(15)
Why would I clear the cache of my web app to annoy my users? I want to do that to clear traces of cached private data. If I tell the browser not to cache, it has to request megabytes of client-side data every time the page loads, which is neither want I want to do.Rysler
@rFactor I'm not saying you would, I am saying that if that were possible, some people would.Azov
@rFactor What are you sending that requires the client to "request megabytes of data every time the page loads"?Azov
no one would, because obviously it would not be possible. Just like you can't run scripts on another origin does not mean you can't run a script on your origin. If you can't clear cache on a remote origin, that's logical, but why could I not clear cache of the origin I am executing the code? There's no reason why not to, so I am looking if there's a solution to that, but it looks like it's not possible. If you are so curious I can tell you that I have a large application with a lot of CSS, HTML and JS compiled to about 6 MB.Rysler
@rFactor That's waaaay too much.Azov
6MB ? Even if you have 100 CSS files you should load only that which is required for that page to minimize bandwidth.Versify
Please explain how no matter the implementation, this would be a security issue? This could be implemented safely.Reprobation
Maybe I didn't get enough sleep last night, in what ways would it be a security issue, when a web app could clear (not alter) cache? How could you exploit that?Sampler
Hi There are situations when one needs to clear cache automatically. when the web app is in development phase, there is constant change to the css,js and html code. So everytime a change is made and the code is updated to server, and other users / team members who would like to view ur changes have to manually clear cache to view changes. especially change in images, css etc. Its annoying if the end user has to clear cache everytime. to automate that we would like to clear cache via meta tags.Glendaglenden
The question you linked to does not support the assertion that "Using SSL also makes some browsers not use caching unless explicitly told to." It says that HTTPS caching works like HTTP caching.Jamey
This seems to fail in Chrome. Browser seems to totally ignore it. At least on localhost.Stimulative
@Stimulative I too faced similar issue on my chrome. I ended up changing .htaccess file. See my below answer for referenceRoping
2023: See the Clear-Site-Data HTTP header, through which the server can instruct a client web browser to clear the website cache for its domain/subdomain, regardless of earlier Cache-Control headers. (Intermediate caches may still have the data cached though and may not respect the header.)Duomo
@Duomo Thanks, I incorporated that into the answerAzov
in the link for Clear-Site-Data Safari is clearly marked as not having it, so not actually cross-browser.Sean
K
43

It's possible, you can simply use jQuery to substitute the 'meta tag' that references the cache status with an event handler / button, and then refresh, easy,

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

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

NOTE: This solution relies on the Application Cache that is implemented as part of the HTML 5 spec. It also requires server configuration to set up the App Cache manifest. It does not describe a method by which one can clear the 'traditional' browser cache via client- or server-side code, which is nigh impossible to do.

Kriegspiel answered 8/11, 2012 at 15:11 Comment(5)
Is this only an HTML5 feature?Franck
I would say so, and I believe it also it also requires server configuration (to set up the app cache manifest). While this answer offers a solution to the original question, it obscures the fact that it's nigh impossible to clear the traditional browser cache via client- or server-side code.Psychopath
This method seems to bypass the cache and update the content, but when the page is reloaded, it goes back to the previously cached content.Tieratierce
deprecated in favor of service workers developer.mozilla.org/en-US/docs/Web/HTML/…Specialist
service workers don't work on iPhones so you have to use the app cache thereSelfservice
C
29

use html itself.There is one trick that can be used.The trick is to append a parameter/string to the file name in the script tag and change it when you file changes.

<script src="myfile.js?version=1.0.0"></script>

The browser interprets the whole string as the file path even though what comes after the "?" are parameters. So wat happens now is that next time when you update your file just change the number in the script tag on your website (Example <script src="myfile.js?version=1.0.1"></script>) and each users browser will see the file has changed and grab a new copy.

Coricoriaceous answered 21/1, 2017 at 10:31 Comment(5)
for those using some server-side dynamic language, if you can access the file's ctime, (or mtime), you can just add said time behind it. For instance in php, myfile.js?v=<?=filectime('myfile.js');?>, and there you've got yourself an auto updating cache for your resources.Onitaonlooker
I was using this technique for many days. But I noticed today that, the file is still being rendered from cache even after I changed the version part. I was using Chrome. It was showing even after I deleted the file from the server. Anyone have any info why it may not work?Aundrea
This trick works, #1923410Adversity
This is how I've done it ever since about 2002. It may be ugly, but it has always worked. Without brand new HTML 5.0 features, I think this was the ONLY way to be able to both cache a page and choose when to get a new copy (ie: bust the cache).Monophyletic
This technique does enforces a GET request and queries a new file from the perspective of the browser cache, it does however not invalidate the old file still in the cache. Whenever you make a request done already made earlier with the same query (and the browser was instructed to cache) you get back this file from cache. Adding n new queries fills n cache entries. If not done carefully adding random queries pollute the browser cache quickly -> its then rather cache trashing.Sean
M
9

The best idea is to make js file generation with name + some hash with version, if you do need to clear cache, just generate new files with new hash, this will trigger browser to load new files

Metalworking answered 15/9, 2016 at 7:37 Comment(0)
C
9

Here is a single-liner of how you can delete ALL browser network cache using Cache.delete()

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

Works on Chrome 40+, Firefox 39+, Opera 27+ and Edge.

Cyrus answered 21/8, 2020 at 16:17 Comment(1)
This is only for items which scripts (usually in a Service Worker) have explicitly stored using the Cache API. It does not give access to the browser's HTTP(s) cache.Suitable
G
9

You could have the server respond with a Clear Site Data directive that instructs the user agent to clear the site's locally stored data.

For example:

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

That header would instruct the user agent to clear all locally stored data, including:

  • Network cache
  • User agent caches (like prerendered pages, script caches, etc.)
  • Cookies
  • HTTP authentication credentials
  • Origin-bound tokens (such as Channel ID and Token Binding)
  • Local storage
  • Session storage
  • IndexedDB
  • Web SQL database
  • Service Worker registrations

You can send the request using fetch() and do location.reload() afterwards to get a fresh restart.

Galloping answered 19/4, 2021 at 12:56 Comment(1)
This is not supported by Safari and Firefox added support for it in version 63 but then removed support for it in version 94.Sherrard
M
7

On Chrome, you should be able to do this using the benchmarking extension. You need to start your chrome with the following switches:

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

In Chrome's console now you can do the following:

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

As you can tell from above commands, it not only clears the browser cache, but also clears the DNS cache and closes network connections. These are great when you're doing page load time benchmarking. Obviously you don't have to use them all if not needed (e.g. clearCache() should suffice if you need to clear the cache only and don't care about DNS cache and connections).

Monoceros answered 26/7, 2016 at 23:13 Comment(0)
R
7

Initially I tried various programmatic approach in my html, JS to clear browser cache. Nothing works on latest Chrome.

Finally, I ended up with .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>

Tested in Chrome, Firefox, Opera

Reference: https://wp-mix.com/disable-caching-htaccess/

Roping answered 22/10, 2017 at 23:43 Comment(2)
This is the best fix.Garett
It also is the slowest fix and needs an Apache web server which in general is not very good anymore I think,Drusy
M
6

You can now use Cache.delete()

Example:

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)
    }
  }));

Works on Chrome 40+, Firefox 39+, Opera 27+ and Edge.

Morphology answered 17/3, 2018 at 0:31 Comment(1)
Best Answer. Worked perfectlyExsiccate
T
5

location.reload(true); will hard reload the current page, ignoring the cache.
Cache.delete() can also be used for new chrome, firefox and opera.

Theseus answered 16/5, 2017 at 17:4 Comment(2)
This function do not work with Internet explorer and safari browser. Not sure if work with Microsoft Edge.Ganny
Sounds like this might be a firefox-specific quirkBicentenary
I
2

//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 >
Ician answered 10/7, 2018 at 13:15 Comment(3)
It is unclear how this answer works and how it is better than the many existing answer. This could be greatly improved with a description of what approach you're following as well as supporting documentation that shows why that will workSelectman
While appreciated, this does not clear the browser cache, it seems to cache-bust any links on the given page just by adding params.Ambiguity
just iterate over list of link tags and script tags and append query param at end it loads. just simple as itPalmar
O
2

By definining a function for cache invalidate meta tags:

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

You can call:

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

That will insert meta tags for subsequents requests, which will force browser to fetch fresh content. After inserting, you can call location.reload() and this will work in mostly all browsers (Cache.delete() is not working at chrome for ex.)

Oecology answered 22/2, 2022 at 7:3 Comment(0)
A
2

I clear the browser's cache for development reasons. Clearing local storage, session storage, IndexDB, cookies, etc. when the data schema changes. If not cleared, there could be data corruption when syncing data with the database. Cache could also be cleared for security reasons as the OP suggested.

This is the code I use:

caches.keys().then(list => list.map(key => caches.delete(key)))

Simple as that, works like a charm. For more information:

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

Analog answered 2/7, 2022 at 18:7 Comment(0)
S
0

Imagine the .js files are placed in /my-site/some/path/ui/js/myfile.js

So normally the script tag would look like:

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

Now change that to:

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

Now of course that will not work. To make it work you need to add one or a few lines to your .htaccess The important line is: (entire .htaccess at the bottom)

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

So what this does is, it kind of removes the 1111111111 from the path and links to the correct path.

So now if you make changes you just have to change the number 1111111111 to whatever number you want. And however you include your files you can set that number via a timestamp when the js-file has last been modified. So cache will work normally if the number does not change. If it changes it will serve the new file (YES ALWAYS) because the browser get's a complete new URL and just believes that file is so new he must go get it.

You can use this for CSS, favicons and what ever gets cached. For CSS just use like so

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

And it will work! Simple to update, simple to maintain.

The promised full .htaccess

If you have no .htaccess yet this is the minimum you need to have there:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    RewriteRule ^my-site\/(.*)\/ui\-([0-9]+)\/(.*) my-site/$1/ui/$3 [L]
</IfModule>
Serna answered 28/4, 2017 at 9:9 Comment(0)
K
0

Unfortunately accepted answer and others did not work for me in my React project, and I tried to find a method myself. I'm using GitHub Actions to deploy my project automatically on server and I wanted to apply versioning, which seems to be working fine.

So, as it builds the project I just set command to add the timestamp to the css and js files.

    - name: Add timestamp to index.html
      run: |
        timestamp=$(date +%s)
        sed -i "s|\(src=\"/assets/[^\"']*\.js\)|\1?v=$timestamp|g" build/index.html
        sed -i "s|\(href=\"/assets/[^\"']*\.css\)|\1?v=$timestamp|g" build/index.html

It worked file in production and I did not need anything else to do.

Kessiah answered 8/2 at 14:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.