JavaScript hard refresh of current page

Viewed 222465

How can I force the web browser to do a hard refresh of the page via JavaScript?
Hard refresh means getting a fresh copy of the page AND refresh all the external resources (images, JavaScript, CSS, etc.).

6 Answers

Try to use:

location.reload(true);

When this method receives a true value as argument, it will cause the page to always be reloaded from the server. If it is false or not specified, the browser may reload the page from its cache.

More info:

window.location.href = window.location.href

Accepted answer above no longer does anything except just a normal reloading on mostly new version of web browsers today. I've tried on my recently updated Chrome all those, including location.reload(true), location.href = location.href, and <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />. None of them worked.

My solution is by using server-side capability to append non-repeating query string to all included source files reference as like below example.

<script src="script.js?t=<?=time();?>"></script>

So you also need to control it dynamically when to keep previous file and when to update it. The only issue is when files inclusion is performed via script by plugins you have no control to modify it. Don't worry about source files flooding. When older file is unlinked it will be automatically garbage collected.

Changing the current URL with a search parameter will cause browsers to pass that same parameter to the server, which in other words, forces a refresh.

(No guarantees if you use intercept with a Service Worker though.)

  const url = new URL(window.location.href);
  url.searchParams.set('reloadTime', Date.now().toString());
  window.location.href = url.toString();

If you want support older browsers:

if ('URL' in window) {
  const url = new URL(window.location.href);
  url.searchParams.set('reloadTime', Date.now().toString());
  window.location.href = url.toString();
} else {
  window.location.href = window.location.origin 
    + window.location.pathname 
    + window.location.search 
    + (window.location.search ? '&' : '?')
    + 'reloadTime='
    + Date.now().toString()
    + window.location.hash;
}

That said, forcing all your CSS and JS to refresh is a bit more laborious. You would want to do the same process of adding a searchParam for all the src attributes in <script> and href in <link>. That said it won't unload the current JS, but would work fine for CSS.

document.querySelectorAll('link').forEach((link) => link.href = addTimestamp(link.href));

I won't bother with a JS sample since it'll likely just cause problems.

You can save this hassle by adding a timestamp as a search param in your JS and CSS links when compiling the HTML.

For angular users and as found here, you can do the following:

<form [action]="myAppURL" method="POST" #refreshForm></form>
import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  // ...
})
export class FooComponent {
  @ViewChild('refreshForm', { static: false }) refreshForm;

  forceReload() {
    this.refreshForm.nativeElement.submit();
  }
}

The reason why it worked was explained on this website: https://www.xspdf.com/resolution/52192666.html

You'll also find how the hard reload works for every framework and more in this article

explanation: Angular

Location: reload(), The Location.reload() method reloads the current URL, like the Refresh button. Using only location.reload(); is not a solution if you want to perform a force-reload (as done with e.g. Ctrl + F5) in order to reload all resources from the server and not from the browser cache. The solution to this issue is, to execute a POST request to the current location as this always makes the browser to reload everything.

Hard refresh of current page. Put this at end of <body>:

<script>

    var t = parseInt(Date.now() / 10000)

    function addQuery(tag) {
      const url = new URL(tag.href || tag.src);
      url.searchParams.set('r', t.toString());
      tag.href = url.toString();
    }

    function refresh() {
      var x = localStorage.getItem("t");
      localStorage.setItem("t", t);
      if (x != t) addQuery(window.location)
      else {
        var a = document.querySelectorAll("a")
        var n = a.length
        while(n--) addQuery(a[n])
      }
    }

    refresh()

</script>

It is a working code from my homepage that do a forced refresh for every visitor so that any update will show up without a cashing problem.

Extending to querySelectorAll("script, style, img, a") has a problem: The tags after querySelectorAll is not parsed and the script, style and img tags before querySelectorAll has already loaded or is loading. Only the a tags is not yet loaded.

The last time x a refresh is done is stored in localStorage. It is compared to the current time t to prevent a page refresh within 10 seconds. Assuming a parse not take more than 10 sec I managed to stop a page refresh loop. Here is how it works for the visitor:

For a visitor of page the x != t is true, so the addQuery(window.location) will make a current page hard refresh of page because a query string is added to the repeated load of the current page.

The current page hard refresh will be within 10 seconds that is enough to load any html document on any server, so the next time x != t will be false. In that case the addQuery is only used to add query strings to href and src for resource hard refresh.

It do no endless loop because of the if-statement described. The refresh() function can be called by a button or other conditioned ways instead of page load.

To be more specific about what the function do; feel free to change the name. Example: hardRefresh, forcedRefresh, maxRefresh, refreshAll, hardLoad, ...

Related