AJAX boiler-plate - asynchronous/synchronous, GET/POST, allows multiple concurrent requests
Update. 16/12/2008 5:58:37 PM. Updated formatting.
Here is my template AJAX code. It allows for the following:
- Asynchronous or synchronous calls.
- GET or POST request - ensuring that if it is a GET request, the URL is unique.
- POST data sent as part of the POST request.
- Multiple concurrent requests.
When I looked around for boiler-plate AJAX code, I didn't find any decent examples of code that allowed multiple concurrent requests. At the time I was writing a search page that would search files in mutliple locations. For a single search, I wanted to launch a different request to the server for each location. This way, I could update the page separately each time a location specific search finished and make the page look much more responsive.
One issue I came accross is that by default, IE only lets two concurrent requests occur at a time. Firefox was not so restrictive.
Examples of usage.
// url, callBackFunction, async flag, GET flag, post data
// Asynchronous GET request.
sendAjaxRequest("myScript?arg1=22&arg2=4", ajaxReqReturned, true, true, null);
// url, callBackFunction, async flag, GET flag, post data
// Asynchronous POST request.
var postData = "field1=value1&field2=value2";
sendAjaxRequest("myPage.jsp", ajaxReqReturned, true, false, postData);
/**
* Call back function for when the AJAX call to the server returns.
*
* Param request - request object we are responding to
*/
function ajaxReqReturned(request) {
var response = request.responseText;
debug("updatePageForEnvironments with response [" + response + "].");
// Take appropriate actions...
}
Here is the boiler-plate code.
/**
* Writes debug to firebug console
*
* Param message - message to write out
*/
function debug(message) {
if (console) {
console.debug(message);
} else {
alert(message);
}
}
/**
* Send an AJAX request.
*
* Inspiration: http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=20&t=005211
*
* Param url - URL to request
* Param callBackFunction - function to call when the request has returned from
* the server
* Param async - true if the call is asynchronous, false otherwise
* Param get - true if this is a GET request, false if it is a POST
* Param postPayload - post data. Ignore if get is true.
*/
function sendAjaxRequest(url, callBackFunction, async, get, postPayload) {
var method = "GET";
if (get) {
// Prevent browser caching by sending always sending a unique url.
url += "&randomnumber=" + new Date().getTime();
postPayload = null;
} else {
method = "POST"
}
console.info("Sending [" + method + "] request "
+ (async ? "a" : "") + "synchronously to url [" + url + "].");
// Obtain an XMLHttpRequest instance
var req = newXMLHttpRequest();
// Set handler function to receive callback notifications from request.
var handlerFunction = getReadyStateHandler(req, callBackFunction);
req.onreadystatechange = handlerFunction;
req.open(method, url, async);
if (!get) {
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", postPayload.length);
req.setRequestHeader("Connection", "close");
}
req.send(postPayload);
}
/**
* Return: a new XMLHttpRequest object, or false if this browser doesn't
* support it
*/
function newXMLHttpRequest() {
var xmlreq = false;
if (window.XMLHttpRequest) {
// Create XMLHttpRequest object in non-Microsoft browsers
xmlreq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
var avers = [
"Microsoft.XmlHttp",
"MSXML2.XmlHttp",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.5.0"
];
for (var i = avers.length -1; i >= 0; i--) {
try {
xmlreq = new ActiveXObject(avers[i]);
} catch(e) {}
}
if (!xmlreq) {
alert("Unable to create AJAX request object.");
}
}
return xmlreq;
}
/**
* Create and return a call back function that checks for server
* success/failure.
*
* Param req - The XMLHttpRequest whose state is changing
* Param responseHandler - Function to pass the response to
* Return: a function that waits for the specified XMLHttpRequest
* to complete, then passes its XML response to the given handler function.
*/
function getReadyStateHandler(req, responseHandler) {
// Return an anonymous function that listens to the XMLHttpRequest instance
return function () {
// If the request's status is "complete"
if (req.readyState == 4) {
var message = req.getResponseHeader("status");
// Check that a successful server response was received
if (req.status == 200) { //todo: catch 404 error.
// Pass the payload of the response to the handler function
responseHandler(req);
} else if (message != undefined && message != null
&& message.length > 0) {
debug("Error status [" + req.status + "] with message ["
+ message + "].");
}
}
}
}
Comments