Prevent browser caching of jQuery AJAX call result

It looks like if I load dynamic content using $.get(), the result is cached in browser.

Adding some random string in QueryString seems to solve this issue (I use new Date().toString()), but this feels like a hack.

Is there any other way to achieve this? Or, if unique string is the only way to achieve this, any suggestions other than new Date()?

Answers:

Answer

I use new Date().getTime(), which will avoid collisions unless you have multiple requests happening within the same millisecond:

$.get('/getdata?_=' + new Date().getTime(), function(data) {
    console.log(data); 
});

Edit: This answer is several years old. It still works (hence I haven't deleted it), but there are better/cleaner ways of achieving this now. My preference is for this method, but this answer is also useful if you want to disable caching for every request during the lifetime of a page.

Answer

The following will prevent all future AJAX requests from being cached, regardless of which jQuery method you use ($.get, $.ajax, etc.)

$.ajaxSetup({ cache: false });
Answer

JQuery's $.get() will cache the results. Instead of

$.get("myurl", myCallback)

you should use $.ajax, which will allow you to turn caching off:

$.ajax({url: "myurl", success: myCallback, cache: false});
Answer

another way is to provide no cache headers from serverside in the code that generates the response to ajax call:

response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setDateHeader( "Expires", 0 );
Answer

All the answers here leave a footprint on the requested URL which will show up in the access logs of server.

I needed a header based solution with no side effect and I found it can be achieved by setting up the headers mentioned in How to control web page caching, across all browsers?.

The result, working for Chrome at least, would be:

$.ajax({
   url: url, 
   headers: {
     'Cache-Control': 'no-cache, no-store, must-revalidate', 
     'Pragma': 'no-cache', 
     'Expires': '0'
   }
});

Answer

Personally I feel that the query string method is more reliable than trying to set headers on the server - there's no guarantee that a proxy or browser won't just cache it anyway (some browsers are worse than others - naming no names).

I usually use Math.random() but I don't see anything wrong with using the date (you shouldn't be doing AJAX requests fast enough to get the same value twice).

Answer

Following the documentation: http://api.jquery.com/jquery.ajax/

you can use the cache property with:

$.ajax({
    method: "GET",
    url: "/Home/AddProduct?",
    data: { param1: value1, param2: value2},
    cache: false,
    success: function (result) {
        // TODO
    }
});
Answer

Of course "cache-breaking" techniques will get the job done, but this would not happen in the first place if the server indicated to the client that the response should not be cached. In some cases it is beneficial to cache responses, some times not. Let the server decide the correct lifetime of the data. You may want to change it later. Much easier to do from the server than from many different places in your UI code.

Of course this doesn't help if you have no control over the server.

Answer

What about using a POST request instead of a GET...? (Which you should anyway...)

Answer

The real question is why you need this to not be cached. If it should not be cached because it changes all the time, the server should specify to not cache the resource. If it just changes sometimes (because one of the resources it depends on can change), and if the client code has a way of knowing about it, it can append a dummy parameter to the url that is computed from some hash or last modified date of those resources (that's what we do in Microsoft Ajax script resources so they can be cached forever but new versions can still be served as they appear). If the client can't know of changes, the correct way should be for the server to handle HEAD requests properly and tell the client whether to use the cached version or not. Seems to me like appending a random parameter or telling from the client to never cache is wrong because cacheability is a property of the server resource, and so should be decided server-side. Another question to ask oneself is should this resource really be served through GET or should it go through POST? That is a question of semantics, but it also has security implications (there are attacks that work only if the server allows for GET). POST will not get cached.

Answer

Maybe you should look at $.ajax() instead (if you are using jQuery, which it looks like). Take a look at: http://docs.jquery.com/Ajax/jQuery.ajax#options and the option "cache".

Another approach would be to look at how you cache things on the server side.

Answer

A small addition to the excellent answers given: If you're running with a non-ajax backup solution for users without javascript, you will have to get those server-side headers correct anyway. This is not impossible, although I understand those that give it up ;)

I'm sure there's another question on SO that will give you the full set of headers that are appropriate. I am not entirely conviced miceus reply covers all the bases 100%.

Answer

For those of you using the cache option of $.ajaxSetup() on mobile Safari, it appears that you may have to use a timestamp for POSTs, since mobile Safari caches that too. According to the documentation on $.ajax() (which you are directed to from $.ajaxSetup()):

Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET.

So setting that option alone won't help you in the case I mentioned above.

Answer

Basically just add cache:false; in the ajax where you think the content will change as the progress go on. And the place where the content wont change there u can omit this. In this way u will get the new response every time

Answer

Internet Explorer’s Ajax Caching: What Are YOU Going To Do About It? suggests three approaches:

  1. Add a cache busting token to the query string, like ?date=[timestamp]. In jQuery and YUI you can tell them to do this automatically.
  2. Use POST instead of a GET
  3. Send a HTTP response header that specifically forbids browsers to cache it
Answer

Now, it's easy to do it by enabling/disabling cache option in your ajax request, just like this

$(function () {
    var url = 'your url goes here';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
                cache: true, //cache enabled, false to reverse
                complete: doSomething
            });
        });
    });
    //ToDo after ajax call finishes
    function doSomething(data) {
        console.log(data);
    }
});
Answer

If you are using IE 9, then you need to use the following in front of your controller class definition:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]

public class TestController : Controller

This will prevent the browser from caching.

Details on this link: http://dougwilsonsa.wordpress.com/2011/04/29/disabling-ie9-ajax-response-caching-asp-net-mvc-3-jquery/

Actually this solved my issue.

Answer

As @Athasach said, according to the jQuery docs, $.ajaxSetup({cache:false}) will not work for other than GET and HEAD requests.

You are better off sending back a Cache-Control: no-cache header from your server anyway. It provides a cleaner separation of concerns.

Of course, this would not work for service urls that you do not belong to your project. In that case, you might consider proxying the third party service from server code rather than calling it from client code.

Answer

If you are using .net ASP MVC, disable the caching on the controller action by adding the following attribute on the end point function: [OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]

Answer

add header

headers: {
                'Cache-Control':'no-cache'
            }
Answer

append Math.random() to the request url

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.