简体   繁体   中英

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?

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.

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

Hope this helps anyone in the future.

I tried (and failed) some sort of randomization to the URL, but it didn't work because the file I was accessing (.json) was being cached as well.

My solution was to add a timestamp to the call to the json file name (similar approach to ones above, slightly modified). This worked perfectly for me (code snippet below).

doSomething('files/data.json?nocache=' + (new Date()).getTime(), function(text){...

I'm very new at all of this so I'm sure there are reasons this isn't a standard/correct solution, but it worked for me.

Removing the element and adding a new element with jQuery (JS also, I think) works for me in Chrome.

// Wordpress Context, selectedImage is an object from the Media Selector Dialog
const imageID = selectedImage.id 
const imageURL = selectedImage.url   

// This is a div with the img as an only child
const logoImageContainer = $('#q1nv0-preview-image-container')
let clone = $(logoImageContainer).find('img').clone()
// In the cloned img object I change the src to the new image      
clone.removeAttr("src").attr('src', imageURL)

// Also I have to remove this in wordpress context:
clone.removeAttr("srcset")
// the div is cleared of the old image      
$('#q1nv0-preview-image-container').empty()
// the new image is added to the div
$(logoImageContainer).prepend(clone)
http.setRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM