In recent times, many websites are adopting the use of calling HTTP Requests and Processing the reply from Javascript.
This is done by utilizing two objects:
XMLHttpRequest
Microsoft.XMLHTTP
These objects are not both used at the same times, they both perform the same operations, but different browsers.
We want to build a function that will stack up pending requests. If we send one request at a time, we can easily identify which instance of the object the reply is associated to.
sets-up a request and adds the HTTP object to currentRequests
adds the function to call with the reply to currentHandlers
appends a timestamp to request to ensure that a cached reply is not received
function sendRequest(docUrl,returnHandler) {
now=new Date(); docUrl+="&rand="+now.valueOf(); // appends the parameters rand to the request URL if (window.XMLHttpRequest){
thisRequest=new XMLHttpRequest(); currentHandlers.push(returnHandler); // adds the return handler to the array thisRequest.onreadystatechange=requestReceived; // set the function to call when the request state changes thisRequest.open("GET",docUrl,true); thisRequest.send(null); currentRequests.push(thisRequest); // adds the XMLHttpRequest object to the array
}else if (window.ActiveXObject){
thisRequest=new ActiveXObject("Microsoft.XMLHTTP"); currentRequests.push(thisRequest); // adds the XMLHTTP object to the array currentHandlers.push(returnHandler); // adds the return handler to the array if (thisRequest){
thisRequest.onreadystatechange=requestReceived; // set the function to call when the request state changes thisRequest.open("GET",docUrl,true); thisRequest.send();
}
}
}
The above function works when the request will use GET parameters i.e. /user.php?username=me&password=pw, where the sent parameters are part of the header.
We can now define a function to to do the same but with POST parameters, where the sent parameters are part of the body.
function sendPostRequest(docUrl,parameters,returnHandler) {
now=new Date(); docUrl+="?rand="+now.valueOf(); // appends the parameters rand to the request URL with ? as the parameters will be send separately if (window.XMLHttpRequest){
thisRequest=new XMLHttpRequest(); currentHandlers.push(returnHandler); // adds the return handler to the array thisRequest.onreadystatechange=requestReceived; // set the function to call when the request state changes thisRequest.open("POST",docUrl,true); thisRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // define the character set thisRequest.setRequestHeader("Content-length", parameters.length); currentRequests.push(thisRequest); // adds the XMLHttpRequest object to the array thisRequest.send(parameters); // sends the request with parameters in the body
}else if (window.ActiveXObject){
thisRequest=new ActiveXObject("Microsoft.XMLHTTP"); currentRequests.push(thisRequest); // adds the XMLHTTP object to the array currentHandlers.push(returnHandler); // adds the return handler to the array if (thisRequest){
thisRequest.onreadystatechange=requestReceived; // set the function to call when the request state changes thisRequest.open("POST",docUrl,true); thisRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); // define the character set thisRequest.setRequestHeader("Content-length", parameters.length); thisRequest.send(parameters); // sends the request with parameters in the body
}
}
}
Now we need to handle the reply, with the function "requestReceived" as defined in the above functions. As the reply will be HTTP, it can be handled by a single function:
function requestReceived() {
reply=""; for (requestIndex=currentRequests.length-1;requestIndex>=0;requestIndex--) { // cycle through the request objects
if (currentRequests[requestIndex].readyState==4) { // checks for state ready
reply=currentRequests[requestIndex].responseText; // gets the response irrespective of the state for debugging purposes currentRequests[requestIndex].getAllResponseHeaders() if (currentRequests[requestIndex].status==200) { // checks for state complete
reply=currentRequests[requestIndex].responseText; // gets the response
} currentRequests[requestIndex]=null; // stops the objects currentRequests.splice(requestIndex,1); // removes the objects thisHandler=currentHandlers[requestIndex]; // retrieve the handler currentHandlers.splice(requestIndex,1); // removes the handler from the array thisHandler(reply); // calls the handler function and send the reply
}
}
}
Now we have the function to easily call server responses from the web page without loading a whole page. For example: