Display a helpful message after a specified period of time if the XMLHttpRequest request has not succeeded. The XMLHttpRequest object opens up a whole new bevy of exceptions that JavaScript programs can raise, having to do with the failure to connect successfully with the server. Why might this occur? Network latency might be the problem, or there might be something wrong with the server. You have no idea how fast your users' connections are, and the server-side program itself may be bogged down handling numerous simultaneous requests, or broken altogether. At any rate, as a developer, you want some control over how long your users wait for your application to respond. As we all know, chances are they won't be willing to wait very longa delay of much more than a few seconds is often considered unacceptable. This hack waits 10 seconds for the server to respond before it displays a friendly message to the user.
The hack uses the JavaScript method of the top-level window object named setTimeout( ).
You can use window object methods without qualifying them with the window object. In other words, using setTimeout( ) alone works as well as using window.setTimeout( ). setTimeout( ) takes a function name or literal as the first argument, then the number of milliseconds (1,000 per second) to wait before calling the method. It returns a numerical value that can be used to cancel the function call. I'll show you that in a moment; in the meantime, here is the code for http_request.js, which encapsulates the initialization and use of XMLHttpRequest. (See "Use Your Own Library for XMLHttpRequest" [Hack #3] for a comprehensive explanation.) Here is the the code, retrofitted to include setTimeout( ) and a new function, timesUp( ): var request = null; var timeoutId; /* Wrapper function for constructing a request object. Parameters: reqType: The HTTP request type, such as GET or POST. url: The URL of the server program. asynch: Whether to send the request asynchronously or not. respHandle: The name of the function that will handle the response. Any fifth parameters represented as arguments[4] are the data a POST request is designed to send. */ function httpRequest(reqType,url,asynch,respHandle){ //Mozilla-based browsers if(window.XMLHttpRequest){ request = new XMLHttpRequest( ); } else if (window.ActiveXObject){ request=new ActiveXObject("Msxml2.XMLHTTP"); if (! request){ request=new ActiveXObject("Microsoft.XMLHTTP"); } } //We test for a null request //if neither ActiveXObject was initialized if(request) { //If the reqType parameter is POST, then the //5th argument to the function is the POSTed data if(reqType.toLowerCase( ) != "post") { initReq(reqType,url,asynch,respHandle); } else { //the POSTed data var args = arguments[4]; if(args != null && args.length > 0){ initReq(reqType,url,asynch,respHandle,args); } } } else { alert("Your browser does not permit the use of all "+ "of this application's features!"); } } /* Initialize a request object that is already constructed */ function initReq(reqType,url,bool,respHandle){ try{ /* Specify the function that will handle the HTTP response */ request.onreadystatechange=respHandle; request.open(reqType,url,bool); timeoutId = setTimeout(timesUp,10000); //If the reqType parameter is POST, then the //5th argument to the function is the POSTed data if(reqType.toLowerCase( ) == "post") { request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); request.send(arguments[4]); } else { request.send(null); } } catch (errv) { alert( "The application cannot contact "+ "the server at the moment. "+ "Please try again in a few seconds.\\n"+ "Error detail: "+errv.message); } } function timesUp( ){ //see below... The request.open( ) method prepares the XMLHttpRequest object for making an HTTP connection. Then the code calls setTimeout( ) just before the request is sent. Here's the rest of the code: /* Event handler for XMLHttpRequest; this function is not a part of http_request.js, but would be defined in another code file that is using http_request.js, as in httpRequest("GET",url,true,handleReq); */ function handleReq( ){ if(request.readyState == 4){ //timeoutId is declared in http_request.js //but can be referenced as a global var here clearTimeout(timeoutId); if(request.status == 200){ //do cool stuff... } }//end outer if } function timesUp( ){ request.abort( ); alert("A problem occurred with communicating with "+ "the server program. Please make sure you are connected "+ "to the Internet and try again in a few moments."); } Recall that setTimeout( ) calls the timesUp( ) function in 10 seconds. If 10 seconds pass without request.readyState == 4 returning true (meaning that the HTTP request is complete), which clears the timeout, timesUp( ) aborts the request and displays an alert window to the user. This action stops the request; the user will have to restart the interaction with the application to launch another request.
If the HTTP request completes its network journey without a hitch, the code calls clearTimeout( ) with the aforementioned timeoutId as its parameter. This action cancels the call to timesUp( ) just in time, allowing the application to go on its merry way doing its intended job. |