Wrox Home  
Professional Ajax
by Nicholas C. Zakas, Jeremy McPeak, Joe Fawcett
March 2007, Paperback

XMLHttp GET Requests

It's time to revisit the hidden frame GET example to see how the process could be improved using XMLHttp. The first change will be to GetCustomerData.php, which must be changed from an HTML page to simply return an HTML snippet. The entire file now becomes streamlined:

  header("Content-Type: text/plain");
  $sID = $_GET["id"];
  $sInfo = "";
  $sDBServer = "your.databaser.server";
  $sDBName = "your_db_name";
  $sDBUsername = "your_db_username";
  $sDBPassword = "your_db_password";
  $sQuery = "Select * from Customers where CustomerId=".$sID;

  $oLink = mysql_connect($sDBServer,$sDBUsername,$sDBPassword);
  @mysql_select_db($sDBName) or $sInfo="Unable to open database";
  if($oResult = mysql_query($sQuery) and mysql_num_rows($oResult) > 0) {
  $aValues = mysql_fetch_array($oResult,MYSQL_ASSOC);
  $sInfo = $aValues['Name']."<br />".$aValues['Address']."<br />".
  $aValues['City']."<br />".$aValues['State']."<br />".
  $aValues['Zip']."<br /><br />Phone: ".$aValues['Phone']."<br />".
  "<a href=\"mailto:".$aValues['E-mail']."\">".
  } else {
      $sInfo = "Customer with ID $sID doesn't exist.";


  echo $sInfo;

As you can see, there are no visible HTML or JavaScript calls in the page. All the main logic remains the same, but there are two additional lines of PHP code. The first occurs at the beginning, where the header() function is used to set the content type of the page. Even though the page will return an HTML snippet, it's fine to set the content type as text/plain, because it's not a complete HTML page (and therefore wouldn't validate as HTML). You should always set the content type in any page that is sending non-HTML to the browser. The second added line is towards the bottom, where the $sInfo variable is output to the stream by using the echo command.

In the main HTML page, the basic setup is this:

<p>Enter customer ID number to retrieve information:</p>
<p>Customer ID: <input type="text" id="txtCustomerId" value="" /></p>
<p><input type="button" value="Get Customer Info" 
          onclick="requestCustomerInfo()" /></p>
<div id="divCustomerInfo"></div>
The requestCustomerInfo() function previously created a hidden iframe but now must be changed to use XMLHttp:
function requestCustomerInfo() {
var sId = document.getElementById("txtCustomerId").value;
var oXmlHttp = zXmlHttp.createRequest();
oXmlHttp.open("get", "GetCustomerData.php?id=" + sId, true);
oXmlHttp.onreadystatechange = function () {
    if (oXmlHttp.readyState == 4) {
        if (oXmlHttp.status == 200) {
        } else {
            displayCustomerInfo("An error occurred: " + 

Note that the function begins the same way, by retrieving the ID the user entered. Then, an XMLHttp object is created using the zXml library. The open() method is called, specifying an asynchronous GET request for GetCustomerData.php (which has the aforementioned ID added to its query string). Next comes the assignment of the event handler, which checks for a readyState of 4 and then checks the status of the request. If the request was successful (status of 200), the displayCustomerInfo() function is called with the response body (accessed via responseText). If there was an error (status is not 200), then the error information is passed to displayCustomerInfo().

There are several differences between this and the hidden frame/iframe example. First, no JavaScript code is required outside of the main page. This is important because any time you need to keep code in two different places there is the possibility of creating incompatibilities; in the frame-based examples, you relied on separate scripts in the display page and the hidden frames to communicate with one another. By changing GetCustomerInfo.php to return just the data you're interested in, you have eliminated potential problems with JavaScript calling between these locations. The second difference is that it's much easier to tell if there was a problem executing the request. In previous examples, there was no mechanism by which you could identify and respond to a server error in the request process. Using XMLHttp, all server errors are revealed to you as a developer, enabling you to pass along meaningful error feedback to the user. In many ways, XMLHttp is a more elegant solution than hidden frames for in-page HTTP requests.

Page 1 | Page 2 | Page 3 | Page 4