216

How do I clear a browsers cache with JavaScript?

We deployed the latest JavaScript code but we are unable to get the latest JavaScript code.

Editorial Note: This question is semi-duplicated in the following places, and the answer in the first of the following questions is probably the best. This accepted answer is no longer the ideal solution.

How to force browser to reload cached CSS/JS files?

How can I force clients to refresh JavaScript files?

Dynamically reload local Javascript source / json data

Dylan Brams
  • 2,089
  • 1
  • 19
  • 36
  • 6
    This confuses me: "We deployed the latest javascript code but we unable to get the latest javascript code" – instanceof me Jun 18 '09 at 09:04
  • 17
    I guess you mean, how to force client browsers to use your latest version of javascript and not their cached version - in that case you need Greg's answer. If you want to know how to do it in your own browser, it's David Johnstone's answer. – Benjol Jun 18 '09 at 09:08
  • 1
    http://stackoverflow.com/questions/118884/what-is-an-elegant-way-to-force-browsers-to-reload-cached-css-js-files – understack Jan 23 '12 at 09:50
  • 5
    A common approach is to attach a `?version=xxx` to your JS linked files through a build step. Every new build will request a new version of the JS file. – Ruan Mendes Jun 14 '12 at 14:57
  • 1
    @JuanMendes This does not always work. This same step is suggested when people have issues trying to see the latest favicon. It's just not guaranteed to work. – uSeRnAmEhAhAhAhAhA Mar 30 '14 at 19:14
  • How can i clear the cache when the entire HTML has been cached ? It wont affect even when the version number is added because of cached HTML.Please help – Nandakumar May 22 '15 at 10:57
  • https://stackoverflow.com/questions/32414/how-can-i-force-clients-to-refresh-javascript-files – Dylan Brams Apr 26 '18 at 07:46

23 Answers23

238

Update: See location.reload() has no parameter for background on this nonstandard parameter and how Firefox is likely the only modern browser with support.


You can call window.location.reload(true) to reload the current page. It will ignore any cached items and retrieve new copies of the page, css, images, JavaScript, etc from the server. This doesn't clear the whole cache, but has the effect of clearing the cache for the page you are on.

However, your best strategy is to version the path or filename as mentioned in various other answers. In addition, see Revving Filenames: don’t use querystring for reasons not to use ?v=n as your versioning scheme.

Kevin Hakanson
  • 41,386
  • 23
  • 126
  • 155
  • 6
    Wow, thanks! This works well for an HTML5 Application Cache loaded from a cache.manifest file as well. I had an old manifest that wasn't being removed from memory, so one browser that had it cached just wouldn't show newer files. I typed this in the javascript console, and worked fine. Thanks! – JayCrossler Nov 03 '10 at 14:08
  • 2
    but revving by changing the filename... won't that have you keep all the previous versions in place? otherwise you'll get a lot of failed attempts from search engines and what not to read the older versions (or bookmarked/linked images) – Rodolfo Jun 14 '12 at 15:04
  • 1
    how is that i didn't think in that, tank you – osdamv Dec 17 '12 at 20:25
  • 1
    Is this same as user click on the refresh button? – Sam YC Jan 03 '14 at 07:00
  • 1
    How can i clear the cache when the entire HTML has been cached ? It wont affect even when the version number is added because of cached HTML.Please help – Nandakumar May 22 '15 at 10:57
  • Does this also clear asynchronous loaded resources? http://stackoverflow.com/questions/43073903/does-window-location-reloadtrue-clear-cache-of-asynchronous-loaded-resources – Manuel Mar 28 '17 at 16:09
  • 2
    @Manuel It will only disable accessing the page from cache of the exact url that you called location.reload(true) on. It never clears the original page from the cache as it simply appends a time stamp to the new request, and if there are other calls made asynchronously by this page, those requests will NOT have their caching behaviors disabled. Eg. If you refresh a page with reload(true) that loads some html, and that page has a script that makes a second ajax call for more html to display on the same page, the second request will not have its caching disabled. – J. Schei Jun 29 '17 at 20:08
  • 1
    There is no boolean parameter to the `reload` method. – Armen Michaeli Oct 25 '20 at 17:48
  • 3
    Reload(true) is deprecated, unfortunately – ataraxis Dec 19 '20 at 14:34
  • I found this link in the article very useful: http://particletree.com/notebook/automatically-version-your-css-and-javascript-files/ – soliver Oct 07 '21 at 08:00
  • 1
    according to MDN the *true* argument is limited to Firefox and is not work for all browsers. https://developer.mozilla.org/en-US/docs/Web/API/Location/reload#location.reload_has_no_parameter – Mohammad Javad Khademian Apr 11 '22 at 13:13
123

You can't clear the cache with javascript. A common way is to append the revision number or last updated timestamp to the file, like this:

myscript.123.js

or

myscript.js?updated=1234567890

dippas
  • 58,591
  • 15
  • 114
  • 126
Greg
  • 316,276
  • 54
  • 369
  • 333
  • 9
    Note however that many proxies won't cache a file when it has a query string. See [answer of Kevin Hakanson](http://stackoverflow.com/a/2181544/130121). – chiborg Mar 12 '12 at 15:37
  • 6
    How can i clear the cache when the entire HTML has been cached ? It wont affect even when the version number is added because of cached HTML.Please help – Nandakumar May 22 '15 at 10:57
  • If I can't clear a cache item, then why does [MDN say](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete) that I can? What am I missing? I tried what MDN says but no luck. – Sнаđошƒаӽ Mar 12 '20 at 16:04
47

Try changing the JavaScript file's src? From this:

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

To this:

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

This method should force your browser to load a new copy of the JS file.

Barry Gallagher
  • 6,156
  • 4
  • 26
  • 30
22

Other than caching every hour, or every week, you may cache according to file data.

Example (in PHP):

<script src="js/my_script.js?v=<?=md5_file('js/my_script.js')?>"></script>

or even use file modification time:

<script src="js/my_script.js?v=<?=filemtime('js/my_script.js')?>"></script>
Stack Programmer
  • 679
  • 6
  • 18
Alexandre T.
  • 3,581
  • 1
  • 18
  • 11
  • 3
    Can I verify I understand this correctly?: With option 1, when the file changes, the md5 checksum hash changes, which then changes the url. The browser sees a new url and initiates a fresh load of the file. The get data appended to the url is ignored by the server. If that's the case, pretty damn slick. – Colin Brogan Jan 22 '13 at 21:26
  • 1
    Also, is MD5-ing an entire file processor intensive? I'm considering doing this for ever css and js file, but I'd hate to see a hit to server speed on account of this. – Colin Brogan Jan 22 '13 at 21:34
  • 2
    Using a checksum is a good idea, but it should be done right. Calculating it every request for every file will hit your performance significantly. Querystring is not good for caching too, see other answers. The right usage is to append a checksum (part of?) or version number to the filename and use this new name instead (you can use a build script to do this automagically on deploy). See [grunt](http://gruntjs.com/), [rev](https://github.com/cbas/grunt-rev) and [usemin](https://github.com/yeoman/grunt-usemin). – Frizi Sep 30 '13 at 08:47
11

You can also force the code to be reloaded every hour, like this, in PHP :

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

or

<script type="text/javascript" src="js/myscript.js?v=<?php echo date('YmdHis'); ?>"></script>
phant0m
  • 16,595
  • 5
  • 50
  • 82
Fabien Ménager
  • 140,109
  • 3
  • 41
  • 60
  • 1
    hi, what is "v" and "token" mean? – Sam YC Jul 02 '13 at 03:57
  • 4
    @GMsoF that is just an additional get parameter which is used (in this case) to tell the browser it is a "different" file. So that the browser will discard the cached version and load this one instead. This is often used with the "last modified date" of a file. I hope this makes sense ;-) – Jelmer Jan 02 '14 at 14:17
11

window.location.reload(true) seems to have been deprecated by the HTML5 standard. One way to do this without using query strings is to use the Clear-Site-Data header, which seems to being standardized.

Mygod
  • 2,077
  • 1
  • 19
  • 43
  • This solution, especially with the additional alternative approaches listed in the linked article, is the best one. The other answers forget that our users _already_ have a cached version of the file and we need to forcefully bypass that cache barrier. – maninak Feb 22 '22 at 14:30
8

put this at the end of your template :

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
      } 
   }
}
Souvik Ray
  • 2,899
  • 5
  • 38
  • 70
yboussard
  • 245
  • 2
  • 4
6

try using this

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

To this:

 <script language="JavaScript" src="js/myscript.js?n=1"></script>
Daniel
  • 1,438
  • 6
  • 20
  • 37
5

Here's a snippet of what I'm using for my latest project.

From the controller:

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

From the view:

<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; ?>">

Our publishing process generates a file with the revision number of the current build. This works by URL encoding that file and using that as a cache buster. As a fail-over, if that file doesn't exist, the year and week number are used so that caching still works, and it will be refreshed at least once a week.

Also, this provides cache busting for every page load while in the development environment so that developers don't have to worry with clearing the cache for any resources (javascript, css, ajax calls, etc).

Justin Johnson
  • 30,978
  • 7
  • 65
  • 89
5

or you can just read js file by server with file_get_contets and then put in echo in the header the js contents

albanx
  • 6,193
  • 9
  • 67
  • 97
4

Maybe "clearing cache" is not as easy as it should be. Instead of clearing cache on my browsers, I realized that "touching" the file will actually change the date of the source file cached on the server (Tested on Edge, Chrome and Firefox) and most browsers will automatically download the most current fresh copy of whats on your server (code, graphics any multimedia too). I suggest you just copy the most current scripts on the server and "do the touch thing" solution before your program runs, so it will change the date of all your problem files to a most current date and time, then it downloads a fresh copy to your browser:

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

...the rest of your program...

It took me some time to resolve this issue (as many browsers act differently to different commands, but they all check time of files and compare to your downloaded copy in your browser, if different date and time, will do the refresh), If you can't go the supposed right way, there is always another usable and better solution to it. Best Regards and happy camping.

Luis H Cabrejo
  • 302
  • 1
  • 8
  • 1
    I like this approach, but perhaps I am implementing this in the wrong area? Does anyone know where to add this in a WordPress setup? I added it to the functions.php file, with direct links to the JavaScript and CSS files, but I still had to do a hard reload for the changes to be noticed. – flipflopmedia Jun 22 '17 at 15:24
  • 1
    What you need to do, is at your main html wordpress directory, edit your index.php to call or execute the Touch() command to the files that you need to be refresh and downloaded. I had problems with small pics and js files that got stuck in cache. I tried most methods described to release from memory, but the best way is to load a current fresh correct one. You can acomplish that by just doing the "Touch Thing" as it doesnt modify anything on the file, just updates the current time and date so fools your browser to think its another version of the file and problem fixed. Works on most browsers – Luis H Cabrejo Jun 22 '17 at 19:36
4

Please do not give incorrect information. Cache api is a diferent type of cache from http cache

HTTP cache is fired when the server sends the correct headers, you can't access with javasvipt.

Cache api in the other hand is fired when you want, it is usefull when working with service worker so you can intersect request and answer it from this type of cache see:ilustration 1 ilustration 2 course

You could use these techiques to have always a fresh content on your users:

  1. Use location.reload(true) this does not work for me, so I wouldn't recomend it.
  2. Use Cache api in order to save into the cache and intersect the request with service worker, be carefull with this one because if the server has sent the cache headers for the files you want to refresh, the browser will answer from the HTTP cache first, and if it does not find it, then it will go to the network, so you could end up with and old file
  3. Change the url from you stactics files, my recomendation is you should name it with the change of your files content, I use md5 and then convert it to string and url friendly, and the md5 will change with the content of the file, there you can freely send HTTP cache headers long enough

I would recomend the third one see

John Balvin Arias
  • 2,632
  • 3
  • 26
  • 41
3

I had some troubles with the code suggested by yboussard. The inner j loop didn't work. Here is the modified code that I use with success.

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;
            }
        }
    }
}
Bryan
  • 1,103
  • 12
  • 16
3

If you are using php can do:

 <script src="js/myscript.js?rev=<?php echo time();?>"
    type="text/javascript"></script>
NoobEditor
  • 15,563
  • 19
  • 81
  • 112
  • 4
    Also, this method would re-download the file every time regardless of the actual revision number or changes made to the file, which would effectively disable caching altogether. – Antti29 Sep 18 '14 at 07:51
3

You can also disable browser caching with meta HTML tags just put html tags in the head section to avoid the web page to be cached while you are coding/testing and when you are done you can remove the meta tags.

(in the head section)

<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"/>

Refresh your page after pasting this in the head and should refresh the new javascript code too.

This link will give you other options if you need them http://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/

or you can just create a button like so

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

it refreshes and avoid caching but it will be there on your page till you finish testing, then you can take it off. Fist option is best I thing.

alfmonc
  • 187
  • 5
2

Most of the right answers are already mentioned in this topic. However I want to add link to the one article which is the best one I was able to read.

https://www.fastly.com/blog/clearing-cache-browser

As far as I can see the most suitable solution is:

POST in an iframe. Next is a small subtract from the suggested post:

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

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

There’s a few obvious side effects: this will create a browser history entry, and is subject to the same issues of non-caching of the response. But it escapes the preflight requirements that exist for fetch, and since it’s a navigation, browsers that split caches will be clearing the right one.

This one almost nails it. Firefox will hold on to the stuck object for cross-origin resources but only for subsequent fetches. Every browser will invalidate the navigation cache for the object, both for same and cross origin resources.

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

We tried many things but that one works pretty well. The only issue is there you need to be able to bring this script somehow to end user page so you are able to reset cache. We were lucky in our particular case.

Sergey
  • 21
  • 1
  • 4
  • This did not do anything when I placed it behind the body tag of my page. – David.P Nov 12 '22 at 11:26
  • 1
    Hi David. When we tested it did what we need but it does not mean it should solve your issue by 100%. It was code snippet that provided us the best coverage in different browsers. Also this code does nothing in actual session. You need to refresh page to see whether it helps or not. – Sergey Dec 01 '22 at 08:14
1

I tend to version my framework then apply the version number to script and style paths

<cfset fw.version = '001' />
<script src="/scripts/#fw.version#/foo.js"/>
SpliFF
  • 38,186
  • 16
  • 91
  • 120
1

Cache.delete() can be used for new chrome, firefox and opera.

Jay Shah
  • 3,553
  • 1
  • 27
  • 26
  • Isn't this just part of the Service Workers' API? – BanksySan Jul 16 '19 at 15:58
  • @BanksySan from the MDN docs: `You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.` – Madbreaks Jun 01 '20 at 18:55
  • '-1' from me on this Answer for using "new" + 3 Browsers, "new" doesn't mean anything anymore when looking at this Answer 5 years later in 2021. (Same with "last", "latest", "current" btw...) => Simply mention the ("from") + Version Number(s)... – chivracq Jul 03 '21 at 01:07
  • @chivracq we're not suppose to keep pushing updated list here - there's a link that takes you to the documentation page of supported browsers. Use the link and see the current status. – Jay Shah Jul 12 '21 at 11:23
  • Yeah..., not asking to "keep pushing updated list", just "complaining" about the Word "new" which doesn't mean anything (anymore)... (And Link-only Answers are always fairly "Low-Quality" anyway...) (Hum..., but Thanks for the Follow-up btw...) – chivracq Jul 12 '21 at 13:05
1

I found a solution to this problem recently. In my case, I was trying to update an html element using javascript; I had been using XHR to update text based on data retrieved from a GET request. Although the XHR request happened frequently, the cached HTML data remained frustratingly the same.

Recently, I discovered a cache busting method in the fetch api. The fetch api replaces XHR, and it is super simple to use. Here's an example:

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

Notice that {cache: "no-store"} argument? This causes the browser to bust the cache for that element, so that new data gets loaded properly. My goodness, this was a godsend for me. I hope this is helpful for you, too.

Tangentially, to bust the cache for an image that gets updated on the server side, but keeps the same src attribute, the simplest and oldest method is to simply use Date.now(), and append that number as a url variable to the src attribute for that image. This works reliably for images, but not for HTML elements. But between these two techniques, you can update any info you need to now :-)

  • This won't work for js [import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import). No way to intercept this. – zwcloud Mar 25 '23 at 08:57
0
window.parent.caches.delete("call")

close and open the browser after executing the code in console.

Apoorv
  • 1,338
  • 1
  • 17
  • 18
  • 1
    Some explanation please, what's "call" in the above code? – Anand Rockzz Jul 13 '17 at 17:04
  • @AnandRockzz it's not possible, cache api just is a new type of cache that can be manage with javascipt, so in order to delete something from there, you have had saved it before see developer.mozilla.org/en-US/docs/Web/API/Cache – John Balvin Arias Jul 12 '18 at 00:38
0

Cause browser cache same link, you should add a random number end of the url. new Date().getTime() generate a different number.

Just add new Date().getTime() end of link as like call

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

Output: https://stackoverflow.com/questions.php?1571737901173

EMAM HASAN
  • 19
  • 3
0

I've solved this issue by using ETag

Etags are similar to fingerprints, and if the resource at a given URL changes, a new Etag value must be generated. A comparison of them can determine whether two representations of a resource are the same.

raul7
  • 171
  • 1
  • 10
-3

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

Cache.delete()

Method

Syntax:

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