Section B. Handling the response


B. Handling the response

The request is sent to the server, which returns a document. In 10C we'll take a closer look at what format this document should be (XML, HTML, JSON); in this section we'll treat the nuts and bolts of handling the response.

status

Let's first return to the onreadystatechange event handler used in sendRequest():

[XMLHTTP Speed Meter, lines 120-138, condensed]

function sendRequest(url,callback,postData) {         // more administration         req.onreadystatechange = function () {            if (req.readyState != 4) return;            if (req.status != 200 && req.status != 304) {                   alert('HTTP error ' + req.status);                   return;            }            callback(req);         } } 


First of all, note that this function, which is defined within the body of sendRequest(), has access to its parent function's variables req and callback. This is a practical example of JavaScript's variable scope, which we discussed in 5I.

Warning

Browser incompatibilities ahead


When the response's readyState has become 4, the function checks its status property. This property contains the HTTP status code that the server has returned. What we want is status 200: OK. Opera, though, sometimes returns status code 304: Not Modified. Therefore we see if the status code is 200 or 304; if it isn't, the function shows an alert, and ends.

HTTP Status Codes

Here's a list of all HTTP status codes: http://www.w3.org/Protocols/HTTP/HTRESP.html


Callback function

If the document has been received normally, the callback function is called. This function was defined in the original sendRequest() call:

[XMLHTTP Speed Meter, lines 46 and 120]

sendRequest('ajax_endpoint.php'+queryString, catchData); function sendRequest(url,callback,postData) { 


XMLHTTP Speed Meter sends a request for ajax_endpoint.php and appends the user's postal code and house number as a query string. Furthermore, this call sets catchData() as the callback function, which means that catchData() is called when the document has been loaded.

This callback function receives the entire XMLHttpRequest object, which by now includes the response, as an argument:

[XMLHTTP Speed Meter, lines 134 and 52-53]

callback(req); function catchData(req) {     var returnXML = req.responseXML; 


responseText and responseXML

It's up to the callback functioncatchData(), in the case of XMLHTTP Speed Meterto do something with the response, and obviously the first step is to read it. For this purpose, an XMLHttpRequest object has two properties: responseText and responseXML. The first holds the document as one text string, while the second holds the document as an XML document; such documents are accessible to the W3C DOM.

The format of the returned data determines whether you need responseText or responseXML, and we'll take a closer look at this question in 10C. XMLHTTP Speed Meter has XML as its response format, and therefore uses responseXML.

ResponseXML and Abort() in Mozilla

Occasionally, when you use the abort() method, the responseXML goes missing in Mozilla. I have no idea how to solve this curious bug; your only line of defense is not to use abort() at all.

If this bug occurs, Mozilla also skips readyState 3.


Example: catchData()

The catchData() function of XMLHTTP Speed Meter starts by extracting the responseXML.

[XMLHTTP Speed Meter, lines 52-59]

function catchData(req) {     var returnXML = req.responseXML;     if (!returnXML) return;     var speed = parseInt(returnXML. getElementsByTagName('speed')[0].firstChild.nodeValue);     if (speed != currentSpeed)            moveToNewSpeed(speed);     currentSpeed = speed;     var error = returnXML.getElementsByTagName('message')[0]. firstChild; 


If there is no responseXML for whatever reason, the function ends. If there is responseXML, returnXML now points to its document node.

The script uses a normal getElementsByTagName() call to read out the download speed. After all, the document is an XML document, so all W3C DOM methods and properties work fine (with the exception of getElementById).

The script takes the speed from the XML, and if it's different from the currently shown speed it sends it to the moveToNewSpeed() animation function discussed in 9G. Finally, it sees whether a <message> tag exists in the XML. The server-side programmer and I agreed that any error message would be contained in this tag. If the tag is present, the script shows the text contained in it.

responseXML needs an XML document

responseXML is available only when the returned document actually is XML, i.e., when its MIME type proclaims it to be XML. That means that if you fetch an HTML page or a text file, responseXML is not available.

However, if you make sure that your server sets the MIME type of HTML pages to text/xml, these pages are considered XML documents (provided they're well-formed), and responseXML will be available.

Unfortunately, if you serve all your HTML pages as text/xml, you'll definitely encounter problems, since normal, non-XMLHttp requested HTML pages should be text/html in order for the browser to properly show them.

Here is where setting the User-Agent header of the request to 'XMLHTTP' can come in handy: a server-side script could send HTML pages as text/xml when it encounters this header, but as text/html otherwise.

getResponseHeader

The getResponseHeader() method allows you to read out individual HTTP response headers. The syntax is as follows:

var lastModified = req.getResponseHeader("Last-Modified"); 


getAllResponseHeaders

The getAllResponseHeaders() method gives you a complete list of all HTTP response headers that the server sent back. The syntax is as follows:

var allResponseHeaders = req.getAllResponseHeaders();  




ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net