Home > Programming > IE Caching Ajax Results – How to fix

IE Caching Ajax Results – How to fix


Updated (25/06/2010): Fixed typos in code example
Updated (16/11/2012): Fixed missing comma. 

I have been working on a website recently and one of the pages on the site has a  main functionality of showing dynamic results returned from a AJAX
call to a WCF service.

As I was developing and continuously testing with Firefox I was happy to see that my code was working well; based on the URL the results on the page will differ as expected.
However, When it came to test the page with Internet Explorer the results were dramatically different… No matter what the URL was the same content from my initial request kept appearing on the screen! Quickly enough I realized that it wasn’t something wrong with my code but with IE, after all in Firefox and Chrome it was working just fine.

So naturally, I googled for a solution and found this StackOverflow thread that confirmed to me that this was indeed an issue with IE. Unfortunately, the good answers there were only helpful to those who use jQuery to initiate the AJAX requests but I was using the proxy generated automatically by ASP.NET, so I had to find my own solution as I was unable to find anything useful online.

Below are ways you can use to fix the problem. First, I’ll show how to fix it when using the MS Service Proxy and then how to fix it when using jQuery.

Microsoft Service Proxy

If you’re interested in seeing how to make use of the auto-generated service proxy in your AJAX calls you can refer to an earlier article I wrote a while back: Tying in WCF, JSON and jTemplates.

Unlike jQuery when using the proxy we are another level apart from the actual plumbing code of issuing the request so its not as easy to modify the URL or change some kind of caching property, the proxy does the calling for us and it is generated automatically so making changes to it (not that it would be a good idea) is not readily available to us.

So how can we workaround the problem? The good folks at Microsoft have given us a hook point in the form of an event that is just the right place to intervene.

The MS Ajax library Reference shows that by using a class called WebRequestManager we can hook up to the request pipeline just before the call is made by using the add_invokingRequest method.

Here is the code you can use to make sure Explorer will actually issue a new request and not just use data it cached:

<script type=“text/javascript”>

$(document).ready(function()
{
myInitializeCode();
});

function myInitializeCode()
{
Sys.Net.WebRequestManager.add_invokingRequest(_onServiceRequestInvoke);
}

function _onServiceRequestInvoke(sender, networkRequestEventArgs)
{

var now = new Date();

var requestUrl = networkRequestEventArgs._webRequest._url;

var uniqueUrl = (requestUrl.indexOf(“?”) > -1 ? “&” : “?”) +
“nocache=” + now.getMilliseconds() + now.getSeconds() +
now.getMinutes();

networkRequestEventArgs._webRequest._url = requestUrl + uniqueUrl;
}

</script>

What I did here was to add to every request URL that the proxy makes a unique (enough) parameter so Explorer thinks its a completely different request each time and doesn’t use any cached result.

The framework passes to our event handler (‘_onServiceRequestInvoke‘) method a collection of arguments of which one is the ‘_webRequestwhich encapsulates the information needed to make the call to the server asynchronously. Naturally, one the web request object properties is the URL of the service operation which is being called. By modifying the URL, we trick Explorer to think its a different resource being called each time and so not to return a cached result.

Now we can continue happily making calls to the server without worrying about the browser our users use.

Microsoft did prefix the variables we access with the “_” which is commonly regarded as a private member in the Javascript world so hopefully they wont change their implementation in a way that will break this fix. I dont think it will happen soon but its good to be aware of this and make sure to check whether it still works when MS releases new versions of the library.

jQuery Ajax

If you’re interested in learning how to make calls to a WCF service using jQuery refer to an earlier article I wrote: Creating a Webservice Proxy with jQuery

To fix the same caching problem when using jQuery to issue requests the good news are that its much easier and built into the jQuery library.

One way to disable caching altogether for all jQuery Ajax calls is by using the AjaxSetup function:

$(document).ready(function()
{
$.ajaxSetup({
cache: false
});

});

However, if you do want to have caching enabled for some calls and disabled for others you can change the cache setting per call using the Ajax function:

$.ajax({
type: “GET”,
url: this._baseURL + method,
cache: false,
data: data,
contentType: “application/json; charset=utf-8″,
dataType: “json”,
success: fnSuccess
});

What both approaches will do behind the scenes is actually modify the request URL with a unique parameter to ensure IE doesnt use a cached version.

  1. Paulo
    June 23, 2010 at 15:38

    there are some typos in your code:

    $(document).ready(function()
    {
    Sys.Net.WebRequestManager.add_invokingRequest(_onServiceRequestInvoke);
    });

    function _onServiceRequestInvoke(sender, networkRequestEventArgs)
    {
    var now = new Date();
    var requestUrl = networkRequestEventArgs._webRequest._url;
    var uniqueUrl = (requestUrl.indexOf(“?”) > -1 ? “&” : “?”) + “nocache=” + now.getMilliseconds() + now.getSeconds() + now.getMinutes();
    networkRequestEventArgs._webRequest._url = requestUrl + uniqueUrl;
    }

    • yoavniran
      June 25, 2010 at 10:34

      Thank you Paulo for the feedback, I really appreciate it.
      The typos should be fixed now.
      Yoav.

  2. Dung Le
    August 20, 2010 at 04:34

    Thank you Yoav!

  3. Dung Le
    August 20, 2010 at 05:04

    I tested the first solution, it works perfectly!
    You are a hero Yoavniran!

  4. Dung Le
    August 20, 2010 at 05:37

    $.ajax({
    type: “GET”,
    url: this._baseURL + method,
    cache: false
    data: data,
    contentType: “application/json; charset=utf-8″,
    dataType: “json”,
    success: fnSuccess
    });

    This method does not work for me, i am not sure why. But if you can give a more specific example?

    Thanks!
    D.

    • yoavniran
      August 20, 2010 at 15:40

      Hi Dung,

      Im very happy to hear this post was helpful to you.

      Can you elaborate a bit what is it that doesnt work for you with the jquery example?
      Are you getting an error or what exactly?

  5. November 6, 2012 at 03:24

    There is a comma missing after cache: false

    • Yoav Niran
      November 16, 2012 at 09:55

      thanks, fixed now.

  6. Shailendra Yadav
    August 21, 2014 at 05:35

    This code will work in IE

    $.ajax({
    type: “GET”,
    url: this._baseURL + method,
    cache:$.ajaxSetup({
    cache: false
    }),
    data: data,
    contentType: “application/json; charset=utf-8″,
    dataType: “json”,
    success: fnSuccess
    });

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 315 other followers

%d bloggers like this: