The introduction of XMLHttpRequest (XHR) in browsers in the mid-2000s was a significant milestone for the Web Platform. In this article, we will explore how XHR works, its capabilities, and compare it with other popular alternatives.

Introduction

Back in the day, technologies like GMail and Google Maps seemed revolutionary. These applications heavily relied on XHR to deliver dynamic content. XMLHttpRequest was initially invented by Microsoft in the 1990s and became a de-facto standard as all major browsers implemented it between 2002 and 2006. In 2006, the W3C standardized XMLHttpRequest.

At first, working with XHR across different browsers had its challenges due to inconsistencies. This led to the rise of libraries like jQuery, which provided an easy-to-use abstraction for developers, further popularizing the use of XHR.

An example XHR request

Let’s take a look at a simple example of creating an XHR request:

const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
  if (xhr.readyState === 4) {
    xhr.status === 200 ? console.log(xhr.responseText) : console.error('error');
  }
};
xhr.open('GET', 'https://yoursite.com');
xhr.send();

In the above code, we create an XHR request object and attach a callback function to respond to the onreadystatechange event. We make a GET request to https://yoursite.com and handle the response accordingly.

Additional open() parameters

Apart from specifying the method and URL, we can also provide additional parameters to the open() method. These parameters allow us to customize the request further:

open(method, url, asynchronous, username, password);

By providing these parameters, we can specify other HTTP methods, make the request synchronous or asynchronous, and include credentials for HTTP authentication.

onreadystatechange

During an XHR request, the onreadystatechange event is called multiple times. However, in most cases, we are only interested in the readyState === 4 state, which indicates that the request is complete. The different states are as follows:

  • 1 (OPENED): The request has been initiated.
  • 2 (HEADERS_RECEIVED): The HTTP headers have been received.
  • 3 (LOADING): The response is being downloaded.
  • 4 (DONE): The response has been downloaded.

Aborting an XHR request

To abort an XHR request, we can simply call the abort() method on the XHR object, like so:

xhr.abort();

Comparison with jQuery

If you are using jQuery, the equivalent XHR request can be simplified using its AJAX methods:

$.get('https://yoursite.com', data => {
  console.log(data);
}).fail(err => {
  console.error(err);
});

jQuery provides a concise and easy-to-use syntax for making XHR requests.

Comparison with Fetch

With the introduction of the Fetch API, an alternative to XHR, the code for making an HTTP request has become even more streamlined:

fetch('https://yoursite.com')
  .then(data => {
    console.log(data);
  })
  .catch(err => {
    console.error(err);
  });

The Fetch API simplifies the process of making HTTP requests by providing a promise-based interface.

Cross Domain Requests

It’s important to note that XHR requests are subject to specific security limitations. The same-origin policy restricts access to resources on different servers, unless the server explicitly supports Cross-Origin Resource Sharing (CORS).

Uploading files using XHR

If you need to upload files using XHR, you can refer to my tutorial on how to upload files using XHR. It provides step-by-step instructions on how to handle file uploads using XHR.