Categories
Programming

IE6 AJAX hang on readyState 3

I recently ran into a problem that took me a few days to find a work around for. Running a basic AJAX POST, IE6 would hang up on readyState 3 for 200 seconds, throw an “Unspecified Error“, and then finally perform the action. Having a user wait 200 seconds for the IE6 timeout to come into effect is simply not a solution. All other browsers I tested, including IE7, were not having this problem.

I read on the web that this may come from SSL or from compression on the webserver. I bypassed our SSL check entirely, and it still happened. I did not mess with the servers for http compression though. To me, that is NOT an option to disable. Bandwidth costs would be too much to even consider this a viable solution.

So, I returned to the programming aspect of it. There has to be a code fix somewhere.

Long story short, IE6 doesn’t handle connection closures properly. A typical request looks something like:


function doajax() {
var url = "/script.php";
var params = "x=123&y=456";

//add timestamp to pass a unique param each time to prevent ie caching the ajax object
timestamp = new Date();
tim1 = (timestamp.getTime());
sec1 = timestamp.getSeconds();
ms1 = timestamp.getMilliseconds();
thetime = tim1+sec1+ms1;
params += "&rand="+thetime;

xmlHttp.open('POST',url,true);
xmlHttp.onreadystatechange = alertContents;
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader('If-Modified-Since','Tue, 04 Apr 2006 00:00:00 GMT'); //some date in the past
xmlHttp.setRequestHeader("Content-length", params.length);
xmlHttp.setRequestHeader("Connection", "close");
}
xmlHttp.send(params);

The line in question here is

xmlHttp.setRequestHeader("Connection", "close");

Since this header is effectively applied for each readyState, it ends up hanging up on readyState 3.

The easy fix:
Target ie6 (and other old browsers) to not close the connection.

change the above snippet to:

if(!document.all) {
xmlHttp.setRequestHeader("Connection", "close");
}

I’m not 100% sure of the implications involved in NOT closing the connection, but I haven’t seen any performance impact, and this cleared up the bug right away. No JS errors, and no 200 second waiting. Give it a try and let me know if it works for you as well.