Caching problem in IE with Ajax : A Solution

Hello All,

Problem Definition:
I made my first browser based chat messenger way back in January this year, and I tried making a improved version of it yesterday again. But unfortunately Microsoft continues to give 1000 reasons for a web developer to suicide. They continue to serve the same old buggy browser way back in 2000 and even now.

The problem I was facing with IE7 (I haven’t tested on IE6), while trying to make a browser based chat messenger was that the chat application loads the chat messages from the server successfully only for the first time i.e. when you load the site for the first time. However, after that it continues showing the same old loaded data, even as new messages keep coming in the server. My chat application always worked fine in Firefox, Netscape, Safari and Flock. So what the hell with Internet Explorer.

The Real Problem:
I faced the same problem 6 months back and was facing it again now. Frustrating enough! As a web developer its a reason enough to die. Anyways, I finally tried analyzing the things. I went around installing Wireshark , which lets you see each and every http request made from your computer. Unfortunately, It was just not showing any ajax request being made by my site (opened on IE). What the hell? However, it showed successful ajax requests being made by my site opened on Firefox.

Enough! The problem was clear that, for some reason IE was not allowing the Ajax request being made. Then I went around installing IE Debug Bar, there in the HTTP(S) section you can see each and every single request being made by IE. I restarted IE and opened my site again. There in the HTTP(S) section, I could see ajax request being made successfully every 15 seconds as intended (a live chat application will set that to about 2 seconds). Then why the hell was wireshark not showing the same.On further investigation with DebugBar I found this was what was not allowing my site to make a successful ajax request the second time:

  • In the Headers section of HTTP(S) I could see:
    GET /ajax.php?getchatmessage=true&id=36&username=imoracle HTTP/1.1
    Accept: */*
    Accept-Language: en-in
    Referer: http://altertunes.com/home.php
    UA-CPU: x86
    Accept-Encoding: gzip, deflate
    HTTP/1.1 200 OK
    X-Powered-By: PHP/5.2.5
    Keep-Alive: timeout=5, max=100
    Transfer-Encoding: chunked
    Content-Type: text/html

  • In the Timing section of HTTP(S) I could see:
    Request start time: Thu, 05 Jun 2008 22:29:55
    All request retrieved from cache (no server request)

  • Further, in the Info & Cache section of HTTP(S) I could see:
    URL: http://altertunes.com/ajax.php?getchatmessage=true&id=36&username=imoracle
    Content Type: text/html
    Headers size (bytes): 336
    Data size (bytes): 3
    Total size (bytes): 339
    Transferred data size (bytes): 0
    Cached data: Yes
    Cache File: C:UsersabhiAppDataLocalMicrosoftWindowsTemporary Internet FilesLowContent.IE5O184DNELajax[1].htm
    Cache expires: Thu, 01 Jan 1970 05:30:00
    Cache last modified: Thu, 01 Jan 1970 05:30:00

Hence the conclusion was, IE do make an ajax request every 15 seconds as intended. But as it always reads the content from the the browser cache, it never gets the new messages from the server. And hence, Wireshark was unable to show any request being made from IE browser, as the request never goes out of the computer.

Solution to this disaster:
I tried looking for many solutions available over internet. A few of them asks to set some settings in your browser, which will force browser to read all the data from server directly. But for two reasons you surely won’t like to do this:

  1. You surely would like to cache your various images, css and other files for faster loading of your website.
  2. Next, You simply can’t expect your users to do the settings, just to make sure that your ajax runs on IE.

A few other sites asked to set a header information at the top of the php page. Probably something like this:

header(“Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT”);
header(“Cache-Control: no-store, no-cache, must-revalidate”);
header(“Cache-Control: post-check=0, pre-check=0”,false);
header(“Pragma: no-cache”);

But even after setting the following header IE was not allowing the ajax requests to fetch the data from the server.

Working Solution:
Then I thought of why not make my ajax requests look unique every time it is fired. i.e. if my ajax request seems like this in the firebug:
http://altertunes.com/ajax.php?getchatmessage=true&id=36&name=imoracle

why not make it look like this the next time:
http://altertunes.com/ajax.php?getchatmessage=true&id=36&name=imoracle&timeid=1234.4323

and like this the very next time:
http://altertunes.com/ajax.php?getchatmessage=true&id=36&name=imoracle&timeid=4324.3589

I tried this up and Bingo! My ajax was working just as great, as it was in any other browser.

I simply changed the url in my ajax request from:
http://altertunes.com/ajax.php?getchatmessage=true&id=36&name=imoracle to
http://altertunes.com/ajax.php?getchatmessage=true&id=36&name=imoracle&timeid=(Math.random()*100000)

and yes, I have my chat messenger working great now.

Try out this solution if you are facing a similar problem with your Ajax requests. I will try to test the same in IE6 if I can find one, but I am pretty sure it will work great there too.

Feel free to post your comments and modified solutions if any.

Happy Ajaxing.

  • Aditya

    or may be you can set the Cache control header to no-cache on server side

    Cache-Control: no-cache

    try setting this header in your php script and see if it works..

  • Aditya Lad

    Testing

  • I tried setting them up as i told above.

    I set that to header(”Cache-Control: no-store, no-cache, must-revalidate”); in the PHP page where i have this chat box. But it didn’t helped.

    Do you mean something else, or is this the thing you intended to say ?

    • bhunchal

      u can also use the date() function to generate the time stamp that u are using instead of rand function ………….. this way it will be 100 % accurate as timestamp counts the number of second from the year 1971 …. so there is no chance that it will repeat …..

      var date = new Date();
      var timestamp = date.getTime();
      var i;
      var string=new Array();

      function ajaxload(that) {
      url=”threads.txt?timestamp=” + timestamp;

      try {
      netscape.security.PrivilegeManager.enablePrivilege(“UniversalBrowserRead”);
      } catch (e) {
      //alert(“Permission UniversalBrowserRead denied.”);
      }
      …………………………

      but make sure that u either put “var date = new Date();” inside the ajax calling function or delete the date object at the end of each ajax fetch …. otherwise u wud end up using the same date object everytime …. and hence the same problem again …..

      this works with both IE and Mozilla as far as i know ………..

  • Aditya

    yes in the php page itself if you set the Cache-Control: no-cache the browser will not cache..(not sure about IE though) just check in wireshark if this header is coming in response to your ajax request..

  • well i have tried the thing, by using cache-control, But unfortunately that doesnt work for me in IE7 atleast. For firefox we r not bothered because by default it picks the data from the server.

    Regarding using date() function, yes we can use any of the methods, either date() or rand(). Main aim was how to make sure that IE takes the ajax request as different from before.

  • Truly

    bhai logo kya kya seekh gaye ho ek saal mein,,,,g***d faad di,,,,kuch samjh mein hi nahin aa raha,,,,,but good job all of u,,,,though i dunno wat the job is 😀

  • hehe, truly bhaiya its not so great. It all looks blah blah if you stand on the other side of the fence. But in reality its all crap and can be easily done. 🙂

    Aap bhi aa jao issi field mein, interesting hai. 🙂

  • Truly

    vaise apne ko jitna pata hai usse yeh kaam aise ho sakta hai. When passing the url you can append the random function Math.random(); to the url string like this:

    var urlVar = urlVar + ‘&’ + Math.random();

    This will solve the problem also.

  • Ek dum sahi truly bhaiya…Maan gaye aapko 😛

  • Truly

    hehe….

  • Thank you for this post, this solution worked for me
    here’s how I implemented it

    function getData(dataSource, divID)
    {
    document.getElementById(‘message’).innerHTML=””;
    if(XMLHttpRequestObject)
    {
    dataSource=dataSource+“&timeid=”+(Math.random()*100000);
    var obj = document.getElementById(divID);
    XMLHttpRequestObject.open(“GET”, dataSource);

    XMLHttpRequestObject.onreadystatechange = function ()
    {
    if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)
    {
    obj.innerHTML = XMLHttpRequestObject.responseText;
    }
    }

    XMLHttpRequestObject.send(null);
    }
    }
    I hope this helps

  • Scott

    I too have had the same problem with IE. With high speed connections, these browsers shouldn’t cache anyway or at least default to a no cache state. Unfortunately, our site is a BtoB site and the businesses we deal with all use this crappy browser which should be relegated to the AOL crowd. There, I feel better now.

    • Scott1

      Another Scott here. I couldn’t agree more and have bitched for a few years now. Microsoft, please make no caching the default. If someone needs caching (ie; they are browsing from the f****** moon) then let them set it. I sometimes wonder if MS feels so threatened by web apps that they undermine them. Our site (product) is BtoB ajax and of course our customers all use IE thanks to their 1980’s IT departments.

      I cringe when our customers call, thinking what has Redmond done now to hurt me.

      There, I feel better too.

  • ben

    Thanks for the solution this problem had been bugging me for some time…..

  • what a nice solution it is!thank you for giving a best solution.but i have gotten a better solution in other site.this site below
    IE6 & IE7 makes problem when use xmlhttprequest for ajax

    At first time when I used core ajax using xmlhttprequest. Using this technique we sent parameter as querystring through the url,like this,…more
    http://aspboss.blogspot.com/2010/02/problem-using-ajax-call-in-ie6-and-ie7.html

  • Sven

    @bhunchal

    I tried the timestamp idea.
    Works wonderfully!

  • Ben S-B

    Yes yes yes, genius solution!! I’ve had a major pain in the arse with ajax in my app imtermittently working and then failing in IE6, at last it’s solved. Thank you!

  • Ashraf Taha

    Hi, May I suggest another approach to solve this, and I promise I won’t take more than a second:

    “USE POST INSTEAD OF GET” ….done

    give it a try, and thank me later.
    NOTE: don’t forget to edit the .php file as well not just the javascript.