Creating the XMLHTTPRequest Object

You cannot make use of the XMLHTTPRequest until you have created an instance of it. Creating an instance of an object in JavaScript is usually just a matter of making a call to a method known as the object's constructor. In the case of XMLHTTPRequest, however, you must change this routine a little to cater for the peculiarities of different browsers, as you see in the following section.

Different Rules for Different Browsers

Microsoft first introduced the XMLHTTPRequest object, implementing it in Internet Explorer 5 as an ActiveX object.

Tip

 

ActiveX is a proprietary Microsoft technology for enabling active objects into web pages. Among the available web browsers, it is currently only supported in Microsoft's Internet Explorer. Internet Explorer uses its built-in XML parser, MSXML, to create the XMLHTTPRequest object.

 

Most other browser developers have now included into their products an equivalent object, but implemented as a native object in the browser's JavaScript interpreter.

Because you don't know in advance which browser, version, or operating system your users will have, your code must adapt its behavior on-the-fly to ensure that the instance of the object will be created successfully.

For the majority of browsers that support XMLHTTPRequest as a native object (Mozilla, Opera, and the rest), creating an instance of this object is straightforward. The following line creates an XMLHTTPRequest object called request:

var request = new XMLHTTPRequest();

 

Here we have declared a variable request and assigned to it the value returned from the statement new XMLHTTPRequest(), which is invoking the constructor method for the XMLHTTPRequest object.

To achieve the equivalent result in Microsoft Internet Explorer, you need to create an ActiveX object. Here's an example:

var request = new ActiveXObject("Microsoft.XMLHTTP");

 

Once again, this assigns the name request to the new object.

To complicate matters a little more, some versions of Internet Explorer have a different version of MSXML, the Microsoft XML parser, installed; in those cases you need to use the following instruction:

var request = new ActiveXObject("Msxml2.XMLHTTP");

 

A Solution for All Browsers

You need, therefore, to create a script that will correctly create an instance of a XMLHTTPRequest object regardless of which browser you are using (provided, of course, that the browser supports XMLHTTPRequest).

A good solution to this problem is to have your script try in turn each method of creating an instance of the object, until one such method succeeds. Have a look at Listing 8.1, in which such a strategy is used.

Listing 8.1. Using Object Detection for a Cross-Browser Solution

 

 

function getXMLHTTPRequest()
{
var request = false;
try
  {
    request = new XMLHttpRequest(); /* e.g. Firefox */
  }
catch(err1)
  {
  try
    {
    vrequest = new ActiveXObject("Msxml2.XMLHTTP");
  /* some versions IE */
    }
  catch(err2)
    {
    try
      {
      request = new ActiveXObject("Microsoft.XMLHTTP");
  /* some versions IE */
      }
      catch(err3)
        {
        request = false;
        }
    }
  }
return request;
}

 

Listing 8.1 uses the JavaScript statements try and catch. The try statement allows us to attempt to run a piece of code. If the code runs without errors, all is well; however, should an error occur we can use the catch statement to intervene before an error message is sent to the user and determine what the program should then do about the error.

Tip

 

Note the syntax:

catch(identifier)

Here identifier is an object created when an error is caught. It contains information about the error; for instance, if you wanted to alert the user to the nature of a JavaScript runtime error, you could use a code construct like this:

catch(err)
  {
  alert(err.description);
  }

to open a dialog containing details of the error.

 

 

 

An alternative, and equally valid, technique would be to detect which type of browser is in use by testing which objects are defined in the browser. Listing 8.2 shows this technique.

Listing 8.2. Using Browser Detection for a Cross-Browser Solution

 

 

function getXMLHTTPRequest()
{
var request = false;
if(window.XMLHTTPRequest)
   {
   request = new XMLHTTPRequest();
   } else {
   if(window.ActiveXObject)
     {
     try
         {
         request = new ActiveXObject("Msml2.XMLHTTP");
         }
     catch(err1)
         {
         try
              {
                 request = new ActiveXObject("Microsoft.XMLHTTP");
             }
         catch(err2)
             {
             request = false;
             }
         }
     }
   }
return request;
}

 

In this example we've used the test

if(window.XMLHTTPRequest) { ... }

 

to determine whether XMLHTTPRequest is a native object of the browser in use; if so, we use the constructor method

request = new XMLHTTPRequest();

 

to create an instance of the XMLHTTPRequest object; otherwise, we try creating a suitable ActiveX object as in the first example.

Whatever method you use to create an instance of the XMLHTTPRequest object, you should be able to call this function like this:

var myRequest = getXMLHTTPRequest();

 

Note

 

JavaScript also makes available a navigator object that holds information about the browser being used to view the page. Another method we could have used to branch our code is to use this object's appName property to find the name of the browser:

var myBrowser = navigator.appName;

This would return "Microsoft Internet Explorer" for IE.

 

 

Methods and Properties

Now that we have created an instance of the XMLHTTPRequest object, let's look at some of the object's properties and methods, listed in Table 8.1.

 

Table 8.1. XMLHTTPRequest Objects and Methods

Properties

Description

onreadystatechange

Determines which event handler will be called when the object's readyState property changes

readyState

Integer reporting the status of the request:

0 = uninitialized

1 = loading

2 = loaded

3 = interactive

4 = completed

responseText

Data returned by the server in text string form

responseXML

Data returned by the server expressed as a document object

status

HTTP status code returned by server

statusText

HTTP reason phrase returned by server

 

 

Methods

Description

abort()

Stops the current request

getAllResponseHeaders()

Returns all headers as a string

getresponseHeader(x)

Returns the value of header x as a string

open('method','URL','a')

specifies the HTTP method (for example, GET or POST), the target URL, and whether the request should be handled asynchronously (If yes, a='TRue'the default; if no, a='false'.)

send(content)

Sends the request, optionally with POST data

setRequestHeader('x','y')

Sets a parameter and value pair x=y and assigns it to the header to be sent with the request

 

Over the next few lessons we'll examine how these methods and properties are used to create the functions that form the building blocks of Ajax applications.

For now, let's examine just a few of these methods.

The open() Method

The open() method prepares the XMLHTTPRequest object to communicate with the server. You need to supply at least the two mandatory arguments to this method:

 

For security reasons, the XMLHTTPRequest object is allowed to communicate only with URLs within its own domain. An attempt to connect to a remote domain results in a "permission denied" error message.

Caution

 

A common mistake is to reference your domain as mydomain.com in a call made from www.mydomain.com. The two will be regarded as different by the JavaScript interpreter, and connection will not be allowed.

 

Optionally you may include a third argument to the send request, a Boolean value to declare whether the request is being sent in asynchronous mode. If set to false, the request will not be sent in asynchronous mode, and the page will be effectively locked until the request is completed. The default value of TRue will be assumed if the parameter is omitted, and requests will then be sent asynchronously.

Note

 

A Boolean data type has only two possible values, 1 (or true) and 0 (or false).

 

The send() Method

Having prepared the XMLHTTPRequest using the open() method, you can send the request using the send() method. One argument is accepted by the send() function.

If your request is a GET request, the request information will be encoded into the destination URL, and you can then simply invoke the send() method using the argument null:

objectname.send(null);

 

However, if you are making a POST request, the content of the request (suitably encoded) will be passed as the argument.

objectname.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
objectname.send(var1=value1&var2=value2);

 

In this case we use the setRequestHeader method to indicate what type of content we are including.