XMLHTTP: Super Glue for the Web

By Kyle Patrick


Most ASP developers have at least fiddled with the new XML support that Microsoft has shipped with their latest browsers. Hopefully, some of you have found clever ways to use Extensible Markup Language (XML) to enrich your Web sites. Yet, using only XMLDOM might give one the feeling that something is missing. After all, XML is meant to be used as a data representation and exchange format on the Web, and while it can be used quite satisfactorily to represent data, developers are still forced to rely on Common Gateway Interface (CGI) for data exchange between the browser and server. CGI, of course, offers absolutely no freedom in the form of communication, so it is fairly useless to use with XML. Luckily, Microsoft has provided a much better method to transfer XML, which has gone largely unnoticed.


In the suite of objects that Microsoft packaged with their MSXML parser, perhaps none are more useful or more ignored than the XMLHTTPConnection object. In a very simple sense, it allows one to open an HTTP connection to a server, send some data, and get some data back, all in a few lines of script or code. The data exchanged through the XMLHTTP object is usually XML, but this is not a requirement.


Down to Business



The standard model for this type of interaction would be for the client to send a string of XML text to the server, the server loads the string into an XMLDOM object and parses it, then returns either HTML for the client to display, or another XML string for the client to load into an object and interact with. This serves as an effective form of information transfer, especially when used with Dynamic Hypertext Markup Language (DHTML) to allow dynamic display of the returned information. For example, (this will only work with Internet Explorer 5.0 on the client and server):




<%
if (Request.ServerVariables(“REQUEST_METHOD”) == “POST” )
{//this part runs on the server, in response to the XMLHTTP post
var req= Server.CreateObject(“Microsoft.XMLDOM”);
req.async=false;
req.load(Request); //load the XML sent by the browser
if (req.documentElement.nodeName==”timesheet”) //my usual method for checking the nature of the data sent
{
//do something fun with the timesheet data
Response.write(“<h1>Timesheet Updated!</h1><b>”+req.documentElement.text+”</b>”);
}
}
else
{ %>

<div id=”divDisplay”>The response will be put in here</div>

<input type=”button” onclick=”sendData();” value=”Send it!”>
<script>
function sendData(){
var xmlhttp = new ActiveXObject(“Microsoft.XMLHTTP”);
xmlhttp.Open(“POST”, “http://www.yoursite.com/thispage.asp”, false);
xmlhttp.Send(“<timesheet>An impossibly useless timesheet fragment</timesheet>”);
divDisplay.innerHTML=xmlhttp.responseText;
}
</script>
<% } %>




The client-side script would create the proper COM object, open a connection to the ASP page at www.yoursite.com (using POST as the HTTP method, and asynchrony set to false, so the code waits for the server’s response), send an XML fragment using the Send method, and then fill in the divDisplay area with the response from the server. On the server, the Request object is loaded into an XML document, and then parsed. Servers respond to XMLHTTP connections just like any other HTTP connection, by using the Response object. Note that XMLHTTP doesn’t necessarily validate either the request or the response, so the rigors of XML only need to be used when necessary.


“Clever,” you say. “But why use this instead of CGI?” Well, for one thing, we have client-server interaction between the browser and the Web server that can be done without changing the Web page. As we all know, doing anything through CGI causes the browser to receive an entirely new page, which is a bother for the Web surfer, who has to wait to redownload a page every time they need to do any miniscule thing. It isn’t that pretty for a Web server, either, since it has to take up precious processor cycles and bandwidth sending every part of a new page to the browser. This isn’t too bad once or twice, but anyone who’s been to e-commerce (electronic commerce) or Web-mail sites know how annoying it can be to wait for the same basic page to load again and again.


Also, if one uses XML with CGI for a Web application, the server will generally have to use the form data to create an XML document, and then do something with it. But it takes a fair bit of processing to construct documents in this fashion, especially if a large amount of data is being sent. It is far nicer to simply have the client’s browser create the XML document, and then send the finished product up via XMLHTTP. This helps take some of the strain off of the server and simplify the server-side code.


An example of this sort of situation would be appending data to an XML document on the server. Rather than constantly querying a CGI form in order to construct the XML node that is to be appended to the document, one could just send up the node via XMLHTTP and have the server simply plunk it into the document.


These are the basics of XMLHTTP, the kind of stuff that you’ll find in the examples on the Microsoft Developers Network (MSDN). However, so much more can be done with this method of communication. I’ll run through a few of the uses I’ve found for XMLHTTP in my applications, and any clever developer could find many more ways to make use of this object.


Using XMLHTTP can allow me to build more ambitious Web applications than with CGI (even using our beloved ASPs), simply because you only have to worry about sending the necessary data. Relatively little code can allow a page to have many complex functions, while CGI requires a new page to be generated for each possible action the user can make.

But since not every browser presently supports MSXML, most ASP pages written for nonintranet purposes will need to include support for CGI interaction. It isn’t too difficult to write a page that will accept both CGI and XMLHTTP data, and not mess things up by trying to load the CGI data into an XML document, or parse form values from the XMLHTTP data (both situations will result in nasty error messages). The simplest way to differentiate between the connections on the server is to look at the MIME type of the data. XMLHTTP has an empty string as a MIME type, unless you specify otherwise (check the MSDN link at the bottom for information on how to vary the MIME type). Most CGI forms have the characteristic MIME type of “application/x-www-form-urlencoded.” For example:





<%
if (Request.ServerVariables(“REQUEST_METHOD”) == “POST” )
{
if (Request.ServerVariables(“CONTENT_TYPE”)==”application/x-www-form-urlencoded”)
{//it was a regular form, so respond in a CGI-ish fashion
Response.write(Request.form(“stuff”));
//This is safe to do now, but it would otherwise crash if Request was from XMLHTTP.
}
else
{//It was an XMLHTTP connection, so you can load the Request object into
//an XML document object without worrying about crashing things.
var req= Server.CreateObject(“Microsoft.XMLDOM”);
req.resolveExternals=false;
req.validateOnParse=false;
req.async=false;
req.load(Request);
Response.write(req.documentElement.selectSingleNode(“stuff”).text);
//This is safe to do now, but an error would’ve been thrown if we’d tried to load
//a CGI Request as an XML document.
}
}
else{ %>



This is a safe and clean way of using both CGI and XMLHTTP from the same ASP page. This is useful because it allows you to make use of all of XMLHTTP’s sophistication for Microsoft Internet Explorer 5.0 (MSIE) clients and maintain backwards compatibility for older MSIE or Netscape clients. Alternately, one could use the CGI interface for all Web clients, but set up an XMLHTTP interface for other types of client applications, such as Microsoft Office applications.


The functionality of XMLHTTP isn’t restricted to browsers. I’ve had a huge success using it in Visual Basic for Applications (VBA) code for Microsoft Office. I stumbled onto this idea when I was asked to find a way to update a very decorative Excel spreadsheet using XML data on our company’s server. Excel can load HTML tables on its own, but that wouldn’t work for this page, which had complex formatting. The data could not just be stuck in;, it had to be finessed.


My solution was to write an ASP page to handle the XMLHTTP requests from Excel. A VBA macro would send the request to the server and then load the response into an XML document, which is then parsed and inserted into the proper Excel cells. This is the kind of seamless, one-button solution that will impress your boss, co-workers, or anyone.

Here’s a snippet of VBA code that would function in just this way. It uses XMLHTTP to load some information from the server, then insert it into the spreadsheet.





Public Sub UpdateSheet()
‘Create the xmlhttp object
Dim xmlhttp
Set xmlhttp = CreateObject(“Microsoft.XMLHTTP”)
‘Open a connection and send a request to the server in the form of an XML fragment
Call xmlhttp.Open(“POST”, “http://www.yourserver.com/yourpage.asp”, False)
Call xmlhttp.send(“<reqtimesheet user=’jimbob’/>”)
‘Create an xml document object, and load the server’s response
Dim xmldoc
Set xmldoc = CreateObject(“Microsoft.XMLDOM”)
xmldoc.async = False
‘Note: the ResponseXml property parses the server’s response, responsetext doesn’t
xmldoc.loadxml(xmlhttp.responsexml)
‘Use the server’s information to update the spreadsheet
‘Note: The structure of the XML document is imaginary and arbitrary, of course.
Worksheets(“TimeSheet”).Range(“A1”).Value = xmldoc.documentelement.getAttribute(“firstname”)
Worksheets(“TimeSheet”).Range(“B1”).Value = xmldoc.documentelement.getAttribute(“lastname”)
Worksheets(“TimeSheet”).Range(“C37”).Value = xmldoc.documentelement.selectSingleNode(“totalhours”).Text
End Sub




The VBA macro is fairly simple. Send a request to the server, stick the server’s response in an XML document, and then update some cells. Of course, one could do many more clever things than this using these techniques, such as upload the data from an Office application into XML on the server (XML in your preferred format, I should add, and not the silly OfficeXML that O2K implements). Or the XML/ASP could be used as a shell around your database, so that applications can have a simple and consistent interface to your database, and changes in the structure of the database wouldn’t require tedious updates of all client applications.




Here is a picture of my Excel application. It queries the server for the available user names and the dates of their timesheets, and lets the user select a name and date. Then the Excel form is updated with the timesheet for that name and date.


I’ve found the XMLHTTP object useful in my programming, as well. I generally write in Visual Basic, Delphi, and Visual J++, and I’ve always found interfacing these languages with online content rather difficult. They all have their own mechanisms for doing anything over a network, and the functionality of these mechanisms vary from language to language. But use of our hallowed XMLHTTP connection can allow these programming languages to contact the server in a very small amount of code. Even better, the interface is the same for all of the languages. As much trouble as it can be, some days you just have to love COM. The native network functionality in a programming language is still useful to understand and use, but it is very clever to simply use XMLHTTP whenever you can get away with it.


As we can see, a more sophisticated method of communication than CGI is required for XML to reach its full potential. Although most public Web applications will need to be made backwards compatible with CGI, with luck more and more developers will make use of the XMLHTTP object when designing complex applications for the Web. It is a fast, easy, free, and powerful method for communication between any client and server applications that support COM objects.


About the Author


Kyle Patrick is a college student by day, and Web and application developer by night. Kyle works at Application Performart Ltd., http://www.performart.net. He is fully HTML 4.0 compliant. He can be reached at kylep42@rice.edu.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read