Search
Close this search box.

Handling timeouts gracefully in AJAX using client-side code

This question was posted to the AZGroups list:

Has anyone come up with a solution for handling timeout issues related to
AJAX, especially with regard to allowing the user to cancel a request?  This
includes cancelling the response to the client as well as notifying
the server that the request has been cancelled, allowing the server to
possibly kill the request process.

AJAX comes in many flavors, so for this sample I’ll just write the most generic callback code possible in Javascript using XMLHttpRequest.  No library necessary, this shows all the actual guts to do an asynchronous callback, with the addition of testing for timeout.  Once you understand this approach, you can then check out your AJAX library of choice to see how it uses XMLHttpRequest, and then add on this timeout code there.  The crux of the solution is to use a setTimeout() at the same time you issue the send(), and have the setTimeout() call your own custom timeout function that does an XMLHttpRequest.abort() like this:

<SCRIPT language=javascript>
// Needed for IE6 and older to replicate the standard XMLHttpRequest object
if (window.ActiveXObject && !window.XMLHttpRequest){window.XMLHttpRequest =
 function(){progIds=new Array("Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.5.0",
 "Msxml2.XMLHTTP.4.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP",
 "Microsoft.XMLHTTP");for(i in progIds){try{return new
 ActiveXObject(progIds[i]);}catch(ex){alert(progIds[i]);}}return null;};}

// Standard asynchonous AJAX code
var xhr = new XMLHttpRequest();
// You would normally trade out the location.href with an actual .ashx
// page.  It's like this here only for testing, thereby requesting this
// same page back from the server.
xhr.open("POST",location.href,true);

// The function that will be called asynchronously when the server sends
// back its response
xhr.onreadystatechange=function(){
   // If you're using the file system instead of a web server then xhr.status
   // will come back as 0, not 200.  And of course if the page isn't found
   // then a web server will send back a status of 404.  xhr.readyState is 4
   // when the page is done.
   if (xhr.readyState == 4 && xhr.status == 200) {
      clearTimeout(xhrTimeout);   // Looks like we didn't time out!
      // Use xhr.responseText to parse the server's response
      alert(xhr.responseText);
   }
}

// Now that we're ready to handle the response, we can make the request
xhr.send("My excellent post info");
// Timeout to abort in 5 seconds
var xhrTimeout=setTimeout("ajaxTimeout();",5000);
function ajaxTimeout(){
   xhr.abort();
   alert("Well dang, the AJAX request timed out.  Did you lose network "+
         "connectivity for some reason?");
   // Note that at this point you could try to send a notification to the
   // server that things failed, using the same xhr object.
}
</SCRIPT>

Hope that helps!  This is the same kind of thing that GMail is doing when you see the “Oops…  Unable to reach the server…” message.  It doesn’t try to pester the server again with a callback if it times out, though.

This article is part of the GWB Archives. Original Author: Lorin Thwaits

Related Posts