Jan 27, 2020 | 6 min read

Axios vs Fetch

One of the fundamental part of a frontend application is to communicate with the servers through the HTTP protocol. JavaScript can send network requests to the server and load new information whenever it is needed without having to reload the page.

The term for that kind of operation is referred to as Asynchronous JavaScript And XML (AJAX) which uses XMLHttpRequest object to communicate with the servers. It can send and receive information in various formats, including JSON, XML, HTML, and text files.

In this guide, we will be looking at how we can make network request and get information from the server asynchronously with fetch() API and axios. We will also be looking into how they can be used to perform different operations.

Fetch

The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network.

The fetch() method takes one mandatory argument, the path to the resource you want to fetch, and returns a Promise that resolves with an object of the built-in Response class as soon as the server responds with headers.

The code below demonstrates a very basic fetch request in which we are fetching a JSON file across the network.

fetch("examples/example.json") .then((response) => { // Do stuff with the response }) .catch((error) => { console.log("Looks like there was a problem: \n", error); });

The second argument that the fetch() method takes is the request object.

{ method: 'POST', // *GET, POST, PUT, DELETE, etc. mode: 'cors', // no-cors, *cors, same-origin cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached credentials: 'same-origin', // include, *same-origin, omit headers: { 'Content-Type': 'application/json' }, redirect: 'follow', // manual, *follow, error referrerPolicy: 'no-referrer', // no-referrer, *client body: JSON.stringify(data) // body data type must match "Content-Type" header }

Once a Response is retrieved, the returned object contains the following properties:

  • response.body - A simple getter exposing a ReadableStream of the body contents
  • response.bodyUsed: Stores a Boolean that declares whether the body has been used in a response yet
  • response.headers - The Headers object associated with the response
  • response.ok - A boolean indicating whether the response was successful or not
  • response.redirected - Indicates whether or not the response is the result of a redirect
  • response.status - The status code of the response
  • response.statusText - The status message corresponding to the status code
  • response.type - The type of the response
  • response.url - The URL of the response

There are a number of methods available to define what the body content is, in various formats:

  • response.json() – parse the response as JSON
  • response.text() – read the response and return as text
  • response.formData() – return the response as FormData object
  • response.blob() – return the response as Blob
  • response.arrayBuffer() – return the response as ArrayBuffer

Axios

Axios is a Javascript library used to make http requests from node.js or XMLHttpRequests from the browser and it supports the Promise API that is native to JS ES6.

Some core features of axios according to the documentation are:

  • It can be used intercept http requests and responses
  • It automatically transform request and response data
  • It enable client side protection against XSRF
  • It has built-in upport for download progress
  • It has the ability to cancel requests

Axios does not come as a native JavaScript API so we will have to manually import into our project. To get started, we will have to include as follows:

  • Using cdn

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  • Using npm

    npm install axios
  • Using bower

    bower install axios

And making a request is as follows:

axios .get("examples/example.json") .then((response) => { // handle success console.log(response); }) .catch((error) => { // handle error console.log(error); });

Axios also provides more functions to make other network requests as well, matching the HTTP verbs that you wish to execute, such as:

  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.options(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])

You can check out the comprehensive request config on the official documentation

The response from a request contains the following information

  • response.data - This is the response that was provided by the server
  • response.status - The HTTP status code from the server response
  • response.statusText - HTTP status message from the server response
  • response.headers - The headers that the server responded with
  • response.config - The config that was provided to axios for the request
  • response.request - The request that generated this response

We have been able to familiarize ourselves with the definition and usage of axios and fetch(). Let's focus our attention into how to perform some real world operations with both axios and fetch.

JSON data

There is a two-step process when handling JSON data with fetch(). Firstly, we have to make the actual request and then lastly, we call the .json() method on the response.

fetch("examples/example.json") // first step .then((response) => response.json()) // second step .then((data) => { console.log(data); }) .catch((error) => console.error(error));

Axios automatically transform data json data once the request is resolved, so we do not have to do much here

axios .get("examples/example.json") .then((response) => { console.log(response.data); }) .catch((error) => { console.log(error); });

Error handling

Handling errors with axios is pretty much straight forward because bad responses (like 404 or 500) will reject the promise.

axios .get("examples/example.json") .then((response) => { console.log("response", response); }) .catch((error) => { if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx console.log(error.response.data); } else if (error.request) { // The request was made but no response was received // `error.request` is an instance of XMLHttpRequest in the browser and an instance of // http.ClientRequest in node.js console.log(error.request); } else { // Something happened in setting up the request that triggered an Error console.log("Error", error.message); } console.log(error.config); });

Evaluating the success of responses is particularly important when using fetch() because bad responses (like 404 or 500) still resolve. The only time a fetch promise will reject is if the request was unable to complete. The code would look something like this:

fetch("examples/example.json") .then((response) => { if (!response.ok) { throw Error(response.statusText); } return response.json(); }) .then((data) => { console.log(data); }) .catch((error) => console.error(error));

Intercepting requests and responses

One of the key features of Axios is its ability to intercept HTTP requests. Interceptors can be really helpful when we want to examine or change HTTP requests from our application to the server such as retrieving a token from local storage and include it in all requests.

// Add a request interceptor axios.interceptors.request.use( function (config) { // Do something before request is sent return config; }, function (error) { // Do something with request error return Promise.reject(error); } ); // Add a response interceptor axios.interceptors.response.use( function (response) { // Do something with response data return response; }, function (error) { // Do something with response error return Promise.reject(error); } ); // sent a GET request axios.get("examples/example.json").then((response) => { console.log(response.data); });

By default, fetch() does not provide a way to intercept HTTP requests. We can overwrite the global fetch() method and define our own interceptor, like this:

fetch = ((originalFetch) => { return (...arguments) => { const result = originalFetch.apply(this, arguments); return result.then(console.log("Request was sent")); }; })(fetch); fetch("examples/example.json") .then((response) => response.json()) .then((data) => { console.log(data); });

Conclusion

In this guide, we have been looked at fetch and axios and also check out some real world operations. While axios is widely supported amongst majority of browsers and can also used in the nodejs environment, fetch on the other hand isn't widely supported among old browsers. If you need to support older browsers a polyfill is available.

Here are some useful links to learn more about various use-cases on both axios and fetch