Implementing Ajax via POST Requests

Type in and save the code in Example 17-2 as urlpost.html, but don’t load it into your browser yet.

Example 17-2. urlpost.html
<html><head><title>Ajax Example</title>
</head><body><center />
<h1>Loading a web page into a DIV</h1>
<div id='info'>This sentence will be replaced</div>
<script>

params = "url=oreilly.com"
request = new ajaxRequest()
request.open("POST", "urlpost.php", true)
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
request.setRequestHeader("Content-length", params.length)
request.setRequestHeader("Connection", "close")

request.onreadystatechange = function()
{
    if (this.readyState == 4)
    {
          if (this.status == 200)
          {
               if (this.responseText != null)
               {
                     document.getElementById('info').innerHTML =
                          this.responseText
               }
               else alert("Ajax error: No data received")
          }
          else alert( "Ajax error: " + this.statusText)
    }
}

request.send(params)

function ajaxRequest()
{
    try
    {
          var request = new XMLHttpRequest()
    }
    catch(e1)
    {
          try
          {
               request = new ActiveXObject("Msxml2.XMLHTTP")
          }
          catch(e2)
          {
               try
               {
                     request = new ActiveXObject("Microsoft.XMLHTTP")
               }
               catch(e3)
               {
                     request = false
               }
          }
    }
    return request
}
</script></body></html>

Let’s go through this document line by line, and look at what it does. The first three lines simply set up an HTML document and display a heading. The next line creates a <div> with the ID “info,” containing the text “This sentence will be replaced” by default. Later on, the text returned from the Ajax call will be inserted here.

The next six lines are required for making an HTTP POST Ajax request. The first sets the variable params to a parameter=value pair, which is what we’ll send to the server. Then the Ajax object request is created. After this, the open method is called to set the object to make a POST request to urlpost.php in asynchronous mode. The last three lines in this group set up headers that are required for the receiving server to know that a POST request is coming.

Now we get to the nitty-gritty of an Ajax call, which all hangs on the readyState property. The “asynchronous” aspect of Ajax allows the browser to keep accepting user input and changing the screen, while our program sets the onreadystatechange property to call a function of our choice each time readyState changes. In this case, a nameless (or anonymous) inline function has been used, as opposed to a separate, named function. This type of function is known as a callback function, as it is called back each time readyState changes.

The syntax to set up the callback function using an inline, anonymous function is as follows:

request.onreadystatechange = function()
{
    if (this.readyState == 4)
    {
          // do something
    }
}

If you wish to use a separate, named function, the syntax is slightly different:

request.onreadystatechange = ajaxCallback

function ajaxCallback()
{
    if (this.readyState == 4)
    {
          // do something
    }
}

Looking at Table 17-1, you’ll see that readyState can have five different values. But only one of them concerns us: the value 4, which represents a completed Ajax call. Therefore, each time the new function gets called, it returns without doing anything until readyState has a value of 4. When our function detects that value, it next inspects the status of the call to ensure it has a value of 200, which means that the call succeeded. If it’s not 200, an alert pop-up is displayed containing the error message contained in statusText.

So, having ascertained that the readyState is 4 and the status is 200, the responseText value is tested to see whether it contains a value. If not, an error message is displayed in an alert box. Otherwise, the inner HTML of the <div> is assigned the value of responseText, like this:

document.getElementById('info').innerHTML = this.responseText

What happens in this line is that the element “info” is referenced using the getElementByID method, and then its innerHTML property is assigned the value that was returned by the Ajax call.

After all this setting up and preparation, the Ajax request is finally sent to the server using the following command, which passes the parameters already defined in the variable params:

request.send(params)

After that, all the preceding code is activated each time readyState changes.

The remainder of the document is the ajaxRequest method from Example 17-1, and the closing script and HTML tags.

Now we get to the PHP half of the equation, which you can see in Example 17-3. Type it in and save it as urlpost.php.

As you can see, this is short and sweet, and also makes use of the ever-important SanitizeString function (which should always be used with posted data).

The program uses the file_get_contents PHP function to load in the web page at the URL supplied to it in the POST variable $_POST['url']. The file_get_contents function is versatile, in that it loads in the entire contents of a file or web page from either a local or a remote server—it even takes into account moved pages and other redirects.

Once you have typed in the program, you are ready to call up urlpost.html in your web browser. After a few seconds, you should see the contents of the http://www.oreilly.com front page loaded into the <div> that we created for that purpose. It won’t be as fast as directly loading the web page, because it is transferred twice—once to the server and again from the server to your browser—but the result should look like Figure 17-2.

The oreilly.com front page loaded into a <div>
Figure 17-2. The oreilly.com front page loaded into a <div>

Not only have we succeeded in making an Ajax call and having a response returned back to JavaScript, but we have also harnessed the power of PHP to enable the merging in of a totally unrelated web object. Incidentally, if we had tried to find a way to fetch the oreilly.com web page directly via Ajax (without recourse to the PHP server-side module), we wouldn’t have succeeded, because there are security blocks preventing cross-domain Ajax. So, this little example also illustrates a handy solution to a very practical problem.