Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force Cache-Control: no-cache in Chrome via XMLHttpRequest on F5 reload

I want to ensure that data I request via an AJAX call is fresh and not cached. Therefor I send the header Cache-Control: no-cache

But my Chrome Version 33 overrides this header with Cache-Control: max-age=0 if the user presses F5.

Example. Put a test.html on your webserver with the contents

<script>
    var xhr = new XMLHttpRequest;
    xhr.open('GET', 'test.html');
    xhr.setRequestHeader('Cache-Control', 'no-cache');
    xhr.send();
</script>

In the chrome debugger on the network tab I see the test.html AJAX call. Status code 200. Now press F5 to reload the page. There is the max-age: 0, and status code 304 Not Modified.

Firefox shows a similar behavior. Intead of just overwriting the request header it modifies it to Cache-Control: no-cache, max-age=0 on F5.

Can I suppress this?

like image 290
sod Avatar asked Mar 12 '14 15:03

sod


People also ask

How do I adjust cache-control without cache?

To use cache-control in HTML, you use the meta tag, e.g. The value in the content field is defined as one of the four values below. HTTP 1.1. Allowed values = PUBLIC | PRIVATE | NO-CACHE | NO-STORE.

What happens if you don't set cache-control header?

Without the cache control header the browser requests the resource every time it loads a new(?) page.

How does cache-control no-cache work?

Cache-control: no-cache This directive tells caches that a resource is not available for reuse for subsequent requests to the same URL without checking if the origin server for the resource has changed.

Does browser cache XHR?

XHR responses are cached automatically in the browser cache if your HTTP cache headers permit it.


2 Answers

An alternative would be to append a unique number to the url.

<script>
    var xhr = new XMLHttpRequest;
    xhr.open('GET', 'test.html?_=' + new Date().getTime());
    //xhr.setRequestHeader('Cache-Control', 'no-cache');
    xhr.send();
</script>

timestamp isn't quite unique, but it should be unique enough for your usecase.

like image 199
3 revs, 3 users 88% Avatar answered Sep 19 '22 08:09

3 revs, 3 users 88%


Using a query string for cache control isn't your best option nowadays for multiple reasons, and (only) a few are mentioned in this answer. He even explains the new standard method of version control. Though if you just want to be able to set your request headers, the right way to do it is:

    // via Cache-Control header:
    xhr.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0");
    
    // fallbacks for IE and older browsers:
    xhr.setRequestHeader("Expires", "Tue, 01 Jan 1980 1:00:00 GMT");
    xhr.setRequestHeader("Pragma", "no-cache"); //Edit: I noticed this is required for Chrome some time ago... forgot to mention here

Hope this helps anyone in the future.

like image 22
hewiefreeman Avatar answered Sep 19 '22 08:09

hewiefreeman