Fetch: A modern replacement for XHR

If you have ever had to fetch some JSON from a website without using a library, you will be familiar with XMLHttpRequest. It can be quite tedious to use, which is why all modern browsers now support the much easier fetch.

Fetch offers a simple way of making requests to a server, returning the result in a promise. In the simple example below, we are getting the HTML of the home page of NewInWeb using both XHR and fetch, and logging it out.

// Using XHR
let xhr = new XMLHttpRequest();
xhr.addEventListener('load', () => console.log(xhr.responseText));
xhr.open('GET', 'https://newinweb.com');
xhr.send();

// Using fetch
fetch('https://newinweb.com')
  .then(result => result.text())
  .then(text => console.log(text));

Fetch can also be used to do other types of requests, such as POST. If not specified, as in the above example, GET is assumed. Below is an example of how you might POST to an API. Note the line credentials: 'same-origin'. By default, fetch does not send cookies with a request unless explicitly told using this parameter.

// Using fetch to make a POST request
fetch('https://newinweb.com/api/id', {
  method: 'POST',
  body: JSON.stringify({
    id: 123
  }),
  credentials: 'same-origin' // set to 'include' for cross-origin requests
});

One final thing to be aware of is that fetch does not fail the way you might expect it to, if you are used to jQuery’s ajax function. The promise will always resolve successfully, unless there is no internet connection. Thus you will need to handle HTTP errors yourself, which can be a bit annoying. My suggestion is to throw an error within then so you can still do all your error handling in the catch.

// Handling errors using fetch
fetch('https://newinweb.com/nonexistent.json')
  .then(response => {
    // Any HTTP code in the 200s is good. Anything else is an error.
    if(response.status >= 200 && response.status < 300) {
      return response.json();
    } else {
      let error = new Error(response.statusText);
      // Add the response to the error to help with debugging
      error.response = response;
      throw error;
    }
  })
  .catch(error => console.log(error));

Unfortunately this awkward error handling makes using fetch as a replacement for XHR libraries less likely. However, it is still very useful for simple requests, and makes for much more readable code.

Other recent posts: