26

I need to reload a page using JavaScript and ensure that it does not pull from the browser cache but instead reloads the page from the server. [As elements of the page will have changed in the interim]

On IE and FF I found that the following code worked fine;

window.location.reload(true);

However it does not work on Chrome or Safari.

I tried the following, but also to no avail;

window.location.replace(location.href);
document.location.reload(true);
document.location.replace(location.href);

Is there a solution to this issue?

Findings

After looking into this I have found that this issue is HTTP Protocol handling;

  1. Chrome sends a request with Pragma: no-cache HTTP field
  2. Server responds with Last-Modified: DATE1 field
  3. JS uses location.reload(true) to force a reload from server not cache
  4. Chrome sends a request with If-Modified-Since: DATE1 field
  5. Server responds with HTTP Status 304 Not Modified

The server application is at fault for not noticing the state change in the dynamic page content, and thus not returning a 200. However, Chrome/WebKit is the only browser that sends a If-Modified-Since field when the JS location.reload(true) is called.

I thought I would put my findings here in-case someone else comes across the same issue.

apaderno
  • 28,547
  • 16
  • 75
  • 90
graney
  • 1,365
  • 2
  • 13
  • 20

5 Answers5

21

You can use this hack:

 $.ajax({
        url: window.location.href,
        headers: {
            "Pragma": "no-cache",
            "Expires": -1,
            "Cache-Control": "no-cache"
        }
    }).done(function () {
        window.location.reload(true);
    });
Suhan
  • 1,434
  • 2
  • 13
  • 28
10

To ensure the page isn't loaded from cache you can add some unique number to query:

window.location = location.href + '?upd=' + 123456;

You also can use date instead of 123456

m03geek
  • 2,508
  • 1
  • 21
  • 41
  • However, when a person then navigates to location.href, using a navigation item say, then it loads the old data from the cache. – graney May 23 '12 at 12:28
  • You can set cache policy for those documents, that you don't want to load from cache. You can add such headers to server response: Cache-Control "max-age=7200, must-revalidate" – m03geek May 23 '12 at 12:49
  • By the way in my chrome (21.0.1145) window.location.reload() works fine. – m03geek May 23 '12 at 12:52
  • 1
    OK. The issue has to do with HTTP protocol handshaking. 1. initial Chrome request includes header containing; Pragma: no-cache 2. Server responds with a header containing; Last-Modified: DATE1. 3. JS calls location.reload(true); which should force ignoring the cache 4. Chrome request contains; If-Modified-Since: DATE1. 5: The server responds with; Http status: 304 not modified Other browsers do not include the If-Modified-Since header field when location.load(true) as it is meant to force a get. WebKit browsers do. – graney May 29 '12 at 11:28
  • let url = window.location.href.split('?')[0]; window.location = url + '?upd=' + Math.floor(Math.random() * 100); – Khalid Almannai Mar 31 '23 at 12:27
2

This is what I do to ensure my application file is force reloaded on chrome:

    var oAjax = new XMLHttpRequest;
    oAjax.open( 'get', '/path/to/my/app.js' );
    oAjax.setRequestHeader( 'Pragma', 'no-cache' );
    oAjax.send();
    oAjax.onreadystatechange = function() {
        if( oAjax.readyState === 4 ) {
            self.location.reload();
        }
    }
Juergen Riemer
  • 1,393
  • 2
  • 13
  • 29
1

Try window.location = window.location

TW147
  • 561
  • 2
  • 7
  • 20
  • This, but would pre-pend something like a random string with the timestamp in the query string (either by adding "&timestamp=" or "?timestamp=" depending on if their is a "?" in the path already or not). – Iain Collins May 23 '12 at 12:10
1

Great findings! I just encountered the same issue and this really helps a lot! However, in addition to your finding, it seems that Chrome always sends a GET request for location.reload()...IE/FF is repeating the last request instead.

Roy Ling
  • 1,592
  • 1
  • 14
  • 31