HOLIDAY SALE! Save 50% on Membership with code HOLIDAY50. Save 15% on Mentorship with code HOLIDAY15.

8) Connecting to the Wider Web Lesson

JavaScript XMLHttpRequest

8 min to complete · By Ian Currie

The first way that JavaScript could handle HTTP requests was by way of the XMLHttpRequest. In this lesson you will learn about the XMLHttpRequest and how to use it to make HTTP requests.

Illustration of a lighthouse

Note: This is an older way of making HTTP requests. It is still used in some legacy code, but the preferred way these days is to use the Fetch API. You will learn about the Fetch API in the next lesson.

The reason you're covering it first is because it doesn't involve promises. It allows you to apply the concepts you've learned as part of this course so far to HTTP requests without having to learn a new concept.

You'll learn about promises and the Fetch API in upcoming lesson, though, which offer a much nicer syntax to deal with HTTP requests.

How to Make an XMLHttpRequest

Here is an example of an XMLHttpRequest (XHR):

let xhr = new XMLHttpRequest();
xhr.open("GET", "https://ghibliapi.vercel.app/people");
xhr.send();

In this code you are making a request to the Studio Ghibli API. The first line creates a new XMLHttpRequest object. The second line tells it to make a GET request to the URL. The third line sends the request.

You'll note that this doesn't return anything on the console. This is because the request is asynchronous. It's happening in the background and you can't see it.

You can access the response with xhr.responseText:

console.log(xhr.responseText);

However, you'll need to wait a few seconds before you can actually see the response. If you try to log the response straight away, you'll get an empty string.

How to Make a Callback Run on Success

Its not very convenient to have to wait a few seconds to log the response. The naive approach would be to use setTimeout:

let xhr = new XMLHttpRequest();
xhr.open("GET", "https://ghibliapi.vercel.app/people");
xhr.send();
setTimeout(() => console.log(xhr.responseText), 5000);

Which waits 5 seconds before logging the response. Yet what if the script takes 200ms? Maybe sometimes it takes 10 seconds? Luckily you can set a callback to run when the request arrives:

let xhr = new XMLHttpRequest();
xhr.open("GET", "https://ghibliapi.vercel.app/people");
xhr.onload = () => console.log(xhr.responseText);
xhr.send();

Here you set the onload attribute to be an arrow function that logs the response. This function will run when the request arrives.

Example of an XHR

Here you will see a more complete XHR. As with most things front-end, there are loads of methods and properties you can use as part of the XMLHttpRequest. Here are a few useful ones in action:

let xhr = new XMLHttpRequest();
xhr.open("GET", "https://ghibliapi.vercel.app/people");

xhr.onerror = () => {
  console.log("error");
};
xhr.ontimeout = () => {
  console.log("timeout");
};

xhr.onload = () => {
  let data = JSON.parse(xhr.responseText);
  console.log(data);
  console.log(xhr.status);
};

xhr.send();

Notice the JSON.parse() method making an appearance. Remember that when you send off a JavaScript object, you need to first convert it into a JSON string. Well in the same way, when you get a response, if it's JSON you'll need to parse it back from a JSON string into a JavaScript object. Notice that when you console log this parsed data, it appears differently than when you logged it as a string. Now you can collapse and expand the tree interactively.

When to Add a Body to an XHR

Sometimes APIs require you to send more information in the body of the request. This is mostly the case when you are making a POST request. You can add a body to an XHR like this:

Just as you often receive JSON as a response, bodies are often sent as a JSON too:

let body = {
  hair_color: "Brown",
  eye_color: "Brown",
};

let xhr = new XMLHttpRequest();
xhr.open("POST", "https://https://httpbin.org/post"); // Note the POST method
xhr.send(JSON.stringify(body));

Remember the use of JSON.stringify()from the object chapter? For these requests you need to convert the body object into a string to pass it over the web.

This is a POST request to the httpbin API. It's a useful API for testing HTTP requests. It will send back the body you send it in the response. Here you are sending a body with the hair_color and eye_color properties. You can see the response in the console.

Summary: What Is a XHR - XML HTTP Request

You've taken a step back in time to learn about how JavaScript originally managed HTTP requests with XMLHttpRequest. Although not as modern as the Fetch API, it's still good to understand how things were done historically. In this lesson, you've:

  • Found out that XMLHttpRequest was the first way to handle HTTP requests in JavaScript, setting the groundwork for AJAX (Asynchronous JavaScript and XML) operations.
  • Seen an example of creating an XMLHttpRequest, opening a connection with the .open method, and sending it with .send.
  • Understood that due to the request's asynchronous nature, you need to wait for the response, which isn't available immediately.
  • Learned how to handle the response asynchronously by setting a function on xhr.onload to execute once the response arrives.
  • Explored additional event handlers like xhr.onerror and xhr.ontimeout for error handling and timeouts.
  • Touched on sending data with a request body using JSON.stringify on a POST request, underlining the symmetry with how JSON.parse is used on the response data.