Reason #256794 why IE sucks: Ajax Caching

This installment of Why IE Sucks? is dedicated to the innocent and virtuous developer who has spent hours and hours wondering why their Ajax calls are returning data so stale that it’s inedible to the point of being deadly. Here’s the scene: if you’re using Prototype or Scriptaculous and are wondering why Ajax.Updater or Ajax.Request are “not working” and the server-side call is never being made, relax there’s nothing wrong with what you’re doing, it all has to do with IE’s sick love of caching.

Firefox and any other browser made by developers possessing an IQ of over 50 don’t have this this “feature” as IE likes to call it. The easiest way to avoid this is to not make GET calls at all using Ajax.Request or Ajax.Updater, instead use POST and you’ll be fine. If you’re hell bent on using GET, you will have to make every call made to the server unique. The fastest and easiest way of doing this for me is to append a random number at the end of the query string. In other words, use the parameters option from Ajax.Options and throw in a random number as one of the request parameters:

new Ajax.Request( 'myPage.html', {
   method: 'get',
   parameters: {
      differentiator: Math.floor(Math.random()*50000)
   }
});

As nasty and laughable as the above code is, it works since your final URL will always be something like mypath.html?differentiator=25632 courtesy of the random number being generated. Again, all this can be avoided by just using ‘post’.

So why does IE go out of its way to break our balls? It’s the philosophy of assuming your customers have the exact same needs as the developer who made the piece of software. You’d think after making life miserable enough by not having a debugger for JavaScript, they’d go easy on us when it comes to the most basic things of web development but no, every sweat or tear extracted is a penny earned for Microsoft.

Advertisements

15 thoughts on “Reason #256794 why IE sucks: Ajax Caching

  1. rob

    AJAX can be used to download static content. The reason being that a web page may need hundreds of kilobytes of data… or it might not, it depends on how the client uses the page. The web page requests the static data as-needed, so that the initial page download is kept small. In that situation, caching results is beneficial.

    You can prevent caching by setting the HTTP headers in the returned document accordingly.

    Anyone who has ever done anything in server-side web development knows that browsers like to cache things and that it can create confusion. Welcome to web development, I hope your second week goes better than the first.

    Reply
  2. arsenalist

    Ouch, diss! Well, you’re first paragraph is saying nothing so I’ll ignore that.

    When you’re writing just the client and not the server side, you can’t really set caching headers, now can you Rob? Care to explain why Firefox, Galeon, Netscape, Safari etc. don’t have this “feature”? Even the browsers that do cache are smart enough to know not to cache XHR responses with such fervor as that IS suicide.

    What adds to the “confusion” is when IE decides to cache the GETs and not the POSTs. Internet Explorer sucks, the sooner you come to realize that the better.

    Reply
  3. rob

    In IE, the XHR object can request a page from any location. Other browsers (such as Firefox) take relative paths. this means that the page you request is on the same server as the page you’re viewing. If both documents are on the same server, you should be able to set the headers.

    Considering the way that POST is used and the large amount of data typically sent, its impractical to cache the results. Situations that do benefit from caching would probably use GET.

    Problems with caching results in AJAX applications have been reported since 2005 (note: the term ‘AJAX’ was coined in 2005). If you want to bash IE, at least be current. As far as problems with IE goes, this one is easy to diagnose and has a simple workaround like you mentioned. This is about as minor as browser-compatibility issues get.

    Reply
  4. rob

    The author is correct that IE caches GET requests made with the XHR object and his workaround is ok. But he bashes IE without realizing how simple and well-documented this problem is, and how this ‘feature’ can actually be beneficial. I know that bashing IE is fashionable, but bashing IE for no good reason is so last year.

    Reply
  5. dasmotiu zodalif

    From another point of view, I’m rather pleased that the default action of the browser is to cache it. That is the behaviour I want. There is a centuries-old proverb: One man’s meat is another man’s poison.

    Reply
  6. real_guy_programmer

    Wow, you’re the kinda guy I’m looking for. You solve all of that bull that happens to programmers. I’ve just spent like the last 5 hours trying to solve this shit problem not to mention the countless hours I’ve spent procrastinating on this known problem. Thanks for making my shit life less shitty. To quote Lewis Black: We’ve gone from shitty shitty shitty to stinky farty smelly.

    Reply
  7. John Atkinson

    excellent work around. still not sure why i would ever want to cache something i’m calling with AJAX. seems against 2.0, but i’m sure there are good examples, i just haven’t come across that yet.

    Reply
  8. David Rose

    Changing the method to POST had no effect for my script. But appending a random number as a parameter in the AJAX request url did the trick. Thanks!

    Reply
  9. serious guy

    hey this is a good idea, we were already setting no-cache HTTP headers with ASP and that worked for one project but the exact same code (javascript and ASP anti-caching stuff) didn’t work on another project on another server. I wouldnt believe me either.

    Anyway, the random number on the end of the querystring worked.

    Firefox was fine in all cases btw

    Reply
  10. working

    If using php, put the following headers to response:

    $offset = 120;
    $ExpStr = “Expires: ” . gmdate(“D, d M Y H:i:s”, time() – $offset) . ” GMT”;
    header($ExpStr);
    header(“Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT”);
    header(“Cache-Control: no-cache, max-age=0, must-revalidate”);

    works fine with IE.

    Reply

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