Hack 9. Dig into the HTTP Response


Display the values of various HTTP response headers in addition to or in lieu of a typical server return value.

An HTTP response header is descriptive information, laid out by the HTTP 1.1 protocol, that web servers send requestors along with the actual web page or data. If you have already coded with the XMLHttpRequest object (discussed at the beginning of this chapter), you know that the request.status property equates to an HTTP response status code sent from the server. This is an important value to check before your page does anything cool with the HTTP response.

Status values can include 200 (the request went through okay), 404 (the requested file or URL path was not found), or 500 (internal server error).


However, you might want to see some of the other response headers associated with the request, such as the type of web server software associated with the response (the Server response header) or the content type of the response (the Content-Type header). This hack requests the user to enter a URL in a text field. When the user tabs out of or clicks outside of the text field, the browser displays various HTTP response headers. As usual with Ajax, this happens without a page refresh.

This request object method returns only a subset of the available response headers, including Content-Type, Date, Server, and Content-Length.


Here is the HTML page code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"         "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd"> <html> <head>     <script type="text/javascript" src="/books/4/254/1/html/2/js/hack7.js"></script>     <meta http-equiv="content-type" content="text/html; charset=utf-8" />     <title>view response headers</title>     <link rel="stylesheet" type="text/css" href="/parkerriver/css/hacks.css" /> </head> <body onload="document.forms[0].url.value=urlFragment"> <h3>Find out the HTTP response headers when you "GET" a Web page</h3> <form action="javascript:void%200">     <p>Enter a URL:          <input type="text" name="url" size="20" onblur="getAllHeaders(this.value)">          <span >::press tab when finished editing the               field::</span></p>     <div ></div> </form> </body> </html>

Figure 1-13 shows the page in the Safari browser.

Figure 1-13. Scoping the response


The application prefills the text field with a partial URL (e.g., http:// localhost:8080/) for the user to complete, because the request object cannot send a request to a different host from the host that uploaded the web page to the user. In other words, the partially completed URL provides a hint to the user that the application can only send a request to that specified host.

When the user completes the URL and then presses the Tab key or clicks outside the text field, the text field's onblur event handler is triggered. The event handler is defined as a function named getAllHeaders( ), which passes the URL the user has entered to the request object. The request object then sends a request to the URL and returns the available response headers to the web page.

The following code is from the hack7.js file that the page imports. After showing this code, I explain the parts that deal with displaying the server's response headers. "Detect Browser Compatibility with the Request Object" [Hack #1] explains how to initialize and open an HTTP connection with the request object, otherwise known as XMLHttpRequest. "Handle Request Object Errors" [Hack #8] explains trapping any errors with JavaScript's try/catch/finally statement.

var request; var urlFragment="http://localhost:8080/"; function getAllHeaders(url){     httpRequest("GET",url,true); } //function for XMLHttpRequest onreadystatechange event handler function handleResponse(  ){     try{         if(request.readyState == 4){             if(request.status == 200){                 /* All headers received as a single string */                 var headers = request.getAllResponseHeaders(  );                 var div = document.getElementById("msgDisplay");                 div.className="header";                 div.innerHTML="<pre>"+headers+"</pre>";             } else {                 //request.status is 503 if the application isn't available;                  //500 if the application has a bug                 alert(request.status);                 alert("A problem occurred with communicating between "+                       "the XMLHttpRequest object and the server program.");             }         }//end outer if     } catch (err)   {         alert("It does not appear that the server is "+               "available for this application. Please"+               " try again very soon. \\nError: "+err.message);     } } /* Initialize a request object that is already constructed */ function initReq(reqType,url,bool){     try{         /* Specify the function that will handle the HTTP response */         request.onreadystatechange=handleResponse;         request.open(reqType,url,bool);         request.send(null);     } catch (errv) {         alert(                 "The application cannot contact the server at the moment. "+                 "Please try again in a few seconds." );     } } /* 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. */ function httpRequest(reqType,url,asynch){     //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");         }     }     //the request could still be null if neither ActiveXObject     //initialization succeeded     if(request){         initReq(reqType,url,asynch);     } else {         alert("Your browser does not permit the use of all "+               "of this application's features!");     } }

The interesting stuff takes place in the handleResponse( ) function. This function calls the request object's getAllResponseHeaders( ) method, which returns (rather awkwardly) all the available response headers, preformatted into a string. A developer would probably prefer this value to be returned in JSON format as an associative array, rather than a monolithic string in which extra code is required to pull out individual header information.

To get one header, you can also use request.getResponseHeader( ). An example would be request.getResponseHeader("Content-Type");.


The code then gets hold of the div element, where it will display the header values:

if(request.status == 200){     /* All headers received as a single string */     var headers = request.getAllResponseHeaders(  );     var div = document.getElementById("msgDisplay");     div.className="header";     div.innerHTML="<pre>"+headers+"</pre>"; }...

To provide a CSS style for the message display, the code sets the className property of the div to a class that is already defined in a stylesheet. Here's the stylesheet, which is linked to the web page:

div.header{ border: thin solid black; padding: 10%;  font-size: 0.9em; background-color: yellow} span.message { font-size: 0.8em; }

In this manner, the code dynamically connects a div to a certain CSS class, which is defined by a separate stylesheet. This strategy helps separate DOM programming from presentation decisions. Finally, the div's innerHTML property is set to the returned header values. You use the pre tag to conserve the existing formatting.

You can, alternatively, manipulate the returned string and format the headers in a different way, using a custom function.


Figure 1-14 shows what the browser displays after the user submits a URL.

Figure 1-14. Separate the headers from the chaff





Ajax Hacks
Ajax Hacks: Tips & Tools for Creating Responsive Web Sites
ISBN: 0596101694
EAN: 2147483647
Year: 2006
Pages: 138

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