31

I've setup an app and it works fantastic on Opera and Firefox, but on Google Chrome it caches the AJAX request and will give stale data!

http://gapps.qk.com.au is the app. When ran in Chrome it doesn't even send the AJAX requests, but when tried in another browser it always does the AJAX request and returns data.

Is there any method (Apache/PHP/HTML/JS) to stop Chrome from doing this behavior?

The AJAX call:

function sendAjax(action,domain,idelement) {

                    //Create the variables
                var xmlhttp,
                    tmp,
                    params = "action=" + action
                             + "&domain=" + encodeURIComponent(domain)

                    xmlhttp = new XMLHttpRequest(); 
                //Check to see if AJAX request has been sent
                xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
                        $('#'+idelement).html(xmlhttp.responseText);
                    }
                };
                xmlhttp.open("GET", "ajax.php?"+params, true);
                xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                //console.log(params);
                xmlhttp.send(params);

            }
sendAjax('gapps','example.com','gapps');
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Mattisdada
  • 916
  • 2
  • 12
  • 19
  • What are the headers returned by your PHP script? Make sure they do not allow caching, and returns an appropriate content-type. – mariusnn Jul 13 '12 at 03:30

4 Answers4

36

The browser cache behaves differently on different settings. You should not depend on user settings or the user's browser. It's possible to make the browser ignore headers also.

There are two ways to prevent caching.

--> Change AJAX request to POST. Browsers don't cache POST requests.

--> Better Way & good way: add an additional parameter to your request with either the current time stamp or any other unique number.

params = "action=" + action 
         + "&domain=" + encodeURIComponent(domain) 
         + "&preventCache="+new Date();
Justin
  • 1,881
  • 4
  • 20
  • 40
gaurang171
  • 9,032
  • 4
  • 28
  • 30
  • 1
    I was thinking of this as a solution but i thought it was inelegant, ok thanks! :) – Mattisdada Jul 13 '12 at 04:06
  • 2
    Just for info and peace of mind. this solution is used by major frameworks when you say preventCache to ajax call one example is DOJO. the add some number instead of date – gaurang171 Jul 13 '12 at 04:16
  • Really? This seems like a "hacky" method to me, it works (great), but I would have thought there would be a better method out their as the "official" way of doing it. Thanks again! :) – Mattisdada Jul 13 '12 at 05:50
  • 2
    This is an old question but it still popped up in the top 3 results for my Google Search query. Sending custom server headers (reply from @Mattisdada) is the best way for files that should never be cached. For static files that occasionally need a refresh, send a parameter with the version of the file you want to load (e.g. `params += '&preventCache=1.0.1'`), not the current timestamp. Caching will still work, and changing the version string will refresh the file. – Sébastien Vercammen Dec 24 '18 at 20:26
15

Another alternative to the Javascript solution is to use custom headers: In PHP it would look like this:

<?php
   header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");//Dont cache
   header("Pragma: no-cache");//Dont cache
   header("Expires: Thu, 19 Nov 1981 08:52:00 GMT");//Make sure it expired in the past (this can be overkill)
?>
Mattisdada
  • 916
  • 2
  • 12
  • 19
2

I was using jQuery ajax request when I ran into this problem.

According to jQuery API adding "cache: false" adds a timestamp like explained in the accepted answer:

This only works with GET and HEAD requests though but if you're using POST the browser doesn't cache your ajax request anyways. There's a but for IE8, check it out in the link if needed.

$.ajax({ 
type: "GET",
cache: false, 
});
iknownothing
  • 354
  • 3
  • 9
1

Below line of code worked for me.

$.ajaxSetup({ cache: false });
Hamza Zafeer
  • 2,360
  • 13
  • 30
  • 42