Skip to content
๐Ÿ™ˆ๐Ÿ™‰๐Ÿ™Š A Curious Animal
Go back

Working with the JavaScript XMLHttpRequest object

In the last years JavaScript has become one of the most important programming languages. Probably one of the most famous words related to JavaScript is AJAX (Asynchronous JavaScript and XML). Request from JavaScript are made through the XmlHttpRequest JavaScript object which lets you open connections, send the request and handle data returned by the server. This post is about XMLHttpRequest object, how to use it and how to handle data in a synchronous or asynchronous way.

Creating a XMLHttpRequest instance

Usually the way to create a XMLHttpRequest instance is simply using:

var req = new XMLHttpRequest();

butย unfortunatelyย this canโ€™t work in old versions of Internet Explorer. In IE6 and earlier, XMLHTTP was implemented as an ActiveX object provided by Microsoft XML (MSXML). Beginning with IE7 XMLHTTP is also exposed as a native scripting object. As simple code to solve this:

XMLHttpFactories = [
  function () {
    return new XMLHttpRequest();
  },
  function () {
    return new ActiveXObject("Msxml2.XMLHTTP");
  },
  function () {
    return new ActiveXObject("Msxml3.XMLHTTP");
  },
  function () {
    return new ActiveXObject("Microsoft.XMLHTTP");
  },
];

function createXHRObject() {
  var xhrobject = null;
  for (var i = 0; i < XMLHttpFactories.length; i++) {
    try {
      xhrobject = XMLHttpFactories[i]();
    } catch (e) {
      continue;
    }
    break;
  }
  return xhrobject;
}

var req = createXHRObject();

The XMLHttpRequest methods

Now we know how to get a fresh instance we need to know a bit more about it, how to make requests and how to handle responses.

Note: Visit the W3C page, referenced below at references section, for a more in depth detail explanation.

Controlling request metadata variables

When making request we could be interested to control things like: target url, the http method used to make the request, set any http header parameter, set the data to be sent, etc Next is a brief description of the methods that allows us to do that.

Handling response data

Once a request is sent we get a response object (donโ€™t worry youโ€™ll some samples in a while). This object has the next important methods and attributes:

Examples: lets play

The most used http methods in AJAX are by far GET and POST, so lets go to take a look on how to use them.

Synchronous request using GET

Next code shows a synchronous request to get content via GET method. It is important to note the โ€˜sendโ€™ method blocks until the request is done. After that you can get the response data.

// The 'false' flag means it is a synchronous request
req.open("GET", "some_url", false);
// This is blocked until request is done and a response is ready
req.send(null);
// If things goes fine then get result
if (req.readyState == 4 && req.status == 200) {
  alert(req.responseText);
}

To ensure request was doneย successfullyย you need to check the readyState and status attributes. In addition, if you need to pass any arguments you can do attaching it to the URL (like a GET request on your browser):

req.open("GET", "some_url?param1=value1&m2=value2", false);

Asynchronous request using POST

Now we are going to see the opposite sample. Next is an asynchronous request using POST method:

// The 'true' flag means it is an asynchronous request
req.open("POST", some_url, true);
// This is called once the request is done
req.onreadystatechange = function () {
  // If things goes fine then get result
  if (req.readyState == 4 && req.status == 200) {
    alert(req.responseText);
  }
};
// You must set the content type of the request.
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// In a POST request data must go here
req.send("param1=value1&m2=value2");

The code has some important differences. First, in the โ€˜openโ€™ method the flag is set to true to make it an asynchronous request. Second, in a POST request the data must be set in the โ€˜sendโ€™ method and you must explicitly specify the Content-Type of the data the request is sent. Finally, and the most important, the โ€˜sendโ€™ method doesnโ€™t block the execution. The request is sent and code continues executing so we need to attach an event handler to the โ€˜onreadystatechangeโ€™, this way once the request is done our handler function is executed. Again we need to check the response readyState and status attributes before to getting the results.

Cross Domain Request

Maybe you are thinking XMLHttpRequest object is the solution to create a really rich internet application requesting data from any place and merging it all together in your own web page butโ€ฆ there are restrictions and cross site request(XSR) are one of them. These restrictions are based in the same origin policy.

Basically, when you load a web page from a domain A and supposing that web page contains your JavaScript code, that code is restricted to make requests on the domain A:

proxy1

You canโ€™t make request from a page loaded on domain A to a domain B (your browser avoids it for security reasons):

proxy2

One way to solve it is using your web server (from where you load the web page) as a proxy server. You make the AJAX request to some place on your server and this makes the real request out and returns the results:

proxy3

Next is a possible message you can get when doing cross domain request. Here I load a test page from my local server that tries to load a resource from acuriousanimal domain:

XMLHttpRequest cannot load http://www.acuriousanimal.com/. Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
Uncaught Error: NETWORK_ERR: XMLHttpRequest Exception 101

Cross Origin Resource Sharing and Access-Control-Allow-* headers

To allow cross domain request the so called Cross Origin Resource Sharing (CORS) specification was developed. To use it you need a compatible browser (at least IE8, Chrome 3, FireFox 3.5, Safari 4), otherwise any request to a different domain will simply throw an exception.

How does CORS work? CORS needs client/server cooperations. Before a request is sent the client (browser) adds the โ€˜originโ€™ HTTP header to the request with the url of the client. The server response must contain some Access-Control-Allow-* HTTP headers indicating which urls, methods or headers the client is allowed to user.

In the previous section sample error we have make a request to a server but our url isnโ€™t listed in the Access-Control-Allow-Origin header. Take a look to the different headers you can use at server side to control which clients are allowed to use your services. Here I would like to point the two most used by me:

References


Share this post:

Previous Post
JavaScript animations (tweening): Why maths are important?
Next Post
notemarklet: Transform selected element into a sticky note