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