Wednesday, April 25, 2007

Howto: IE6 and IE7 Ajax caching fix

My company's product frevvo Live Forms makes heavy use of Ajax, especially in the Form Designer. We had to work around a number of interesting "features" in good ol' IE6 (and now IE7). One of IE's stupidest quirks – among the many endearing features that have cost us hours – is that it caches responses to Ajax requests. Doh! By definition, Ajax requests are supposed to be dynamic so caching the responses is one of the dumbest things around.

frevvo's architecture is essentially a Model-View-Controller (MVC) pattern in the browser. I'm doing a bit of hand-waving here but the model in the browser is essentially a stub that updates the actual model on the server using Ajax. When designing a form, if you move a control around or modify one of its properties, your browser will update the server model via Ajax. For large forms or large schemas, browser performance at initial load time is a big issue (more on this later) so Live Forms dynamically generates the XHTML for a Section in the form when it is expanded or a complex element in a schema when it is expanded.

Unfortunately, IE6 and IE7 cache the Ajax responses. No matter how often you refresh, IE will still show the old XHTML. Fortunately, the workaround is relatively simple – just add a random number or timestamp to the URL, as in the block of code below (uses Ajax.Request from prototype):

editControlType: function (controlId, onSuccess,
onFailure, options) {
var requestUrl = this.controlUrl(controlId) + "/editor" +
"?edit=true&random=" + Math.random();
Object.extend(options, {
method:'get',
onSuccess:onSuccess,
onFailure:onFailure,
onException:this.onException
});
new Ajax.Request(requestUrl, options);
}

This is the only reliable solution I've been able to find. Cache control headers don't work reliably either – I haven't been able to figure out IE's algorithm for this. It appears to ignore cache-control headers most of the time.

With the unique random number parameter, IE now thinks it's a brand new URL, and does not display the cached version. Whew!

For the record, I'm not randomly biased against IE. FF and Safari have their own set of issues but, honestly, they're nothing compared to IE.

No comments: