Axios vs. fetch() for making HTTP requests

Axios vs. fetch() for making HTTP requests
Last edit: Apr 30, 2024

The HyperText Transfer Protocol (HTTP) and its more secure version, HTTPS, are used to transfer information and documents. It defines how messages are formatted and transmitted and what actions web servers and browsers should perform in response to various commands. HTTP requests are essential for web development, whether it's interacting with servers or working with APIs. Understanding HTTP requests is crucial for working with any web technology.

In JavaScript, as well as in NodeJS (which is a JavaScript runtime environment), there are two popular libraries for working with HTTP requests: Fetch API and Axios. The choice between them is a matter of debate, with each having its own supporters. In this article, we will compare these two methods to identify their pros and cons and help you choose the most suitable one for your project.

Try Our Ready-Made Solutions for Your Needs

Gain instant access to a wealth of business data on Google Maps, effortlessly extracting vital information like location, operating hours, reviews, and more in HTML…

Get fast, real-time access to structured Google search results with our SERP API. No blocks or CAPTCHAs - ever. Streamline your development process without worrying…

Understanding HTTP Requests

Before diving into Fetch API and Axios, let's briefly cover HTTP requests: what they are, their types, and their components. An HTTP request is a message sent to a server to access a resource. The request specifies the method, URL, headers, and body (if any). There are many HTTP request methods:

  1. GET: fetch() request data from a specified resource. It should not have any effect on the data.
  2. POST: Submits data to be processed to a specified resource, often causing a change in state or side effects on the server.
  3. PUT: Replaces all current representations of the target resource with the uploaded content.
  4. DELETE: Removes specified resources.
  5. HEAD: Similar to GET, but it only requests the headers (not the body of the specified resource).
  6. PATCH: Applies partial modifications to a resource.

After defining the request method, you specify the resource URL. Next, you build the request itself, consisting of headers and a body.

Request headers provide crucial information to the server, such as Acceptable content types (Accept header), Content type being sent (Content-Type header), and Authentication data. The request body is used for sending data with certain requests, like POST or PUT. It can be a form, JSON, XML, or any other format the server expects.

HTTP responses are composed of a status line (including the http status code and a short description), headers, and sometimes a body. The status code provides information about the result of the request. Common status codes include:

  1. 200 OK: The request was successful.
  2. 301 Moved Permanently: The resource has been permanently moved to a new URL.
  3. 400 Bad Request: The request cannot be processed because of bad syntax.
  4. 401 Unauthorized: Authentication is required to access the resource.
  5. 404 Not Found: The requested resource could not be found.
  6. 500 Internal Server Error: A generic error message when the server encounters an unexpected condition.

It's good practice to consider not only the possibility of a successful response but also potential errors when making HTTP requests.

Now that we have an understanding of HTTP requests, their types, components, and expected responses, let's move on to the main topic of this article and compare two popular NodeJS tools for working with them.

A Quick Overview of Fetch and Axios

To effectively compare these tools, let's first understand their definitions and purposes. By understanding the core differences between Fetch API and Axios, we can better evaluate their respective strengths and weaknesses for different use cases.

What is Fetch API

The Fetch API is a native JavaScript interface for making HTTP requests. It's part of the Window and Worker APIs, providing a global fetch() method to send requests. This API was designed to replace the legacy XMLHttpRequest approach, offering a simpler and more powerful tool for working with network requests.

A simple GET request using the fetch():

fetch('https://example.com')
  .then(response => {
    if (!response.ok) {
        throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('There was a problem with your fetch operation:', error));

Fetch API is not a built-in function in Node.js because Node.js lacks a native API for working with HTML or HTTP requests as the browser does. However, using external modules like node-fetch, you can emulate the behavior of the fetch() in a Node.js environment. Once node-fetch is installed, using fetch() in Node.js looks very similar to using it in the browser.

const fetch = require('node-fetch');

fetch('https://example.com')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

The rest of this article will provide examples specifically in the context of JavaScript.

What is Axios

Axios is a popular JavaScript library for making HTTP requests from both browsers and Node.js. It provides a convenient API for making requests to servers and handling responses. Compared to the fetch(), Axios adds several useful features and simplifies some aspects of making requests, such as automatic JSON response parsing and XSRF protection.

It is often used in conjunction with the Cheerio library for web scraping. Cheerio is a fast, flexible, and lean implementation of core jQuery designed specifically for the server. It allows you to select and extract data from HTML documents.

Before diving into a detailed feature comparison, let's explore how to use Axios in both the browser and Node.js environments. The usage is very similar in both cases, with minor differences due to the execution environment.

To use Axios in the browser, add a script tag from the CDN to your HTML file. Then, you can use the axios object to make a GET request.

axios.get('https://example.com')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  })
  .finally(function () {
  });

To use Axios in Node.js, you first need to install the package using npm or yarn. Other than that, there are not many differences:

const axios = require('axios');

axios.get('https://example.com')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  })
  .finally(function () {
  });

Axios is easy to use in both the browser and NodeJS, with minimal to no code differences.

Key Differences and Considerations

Now that we have covered what Axios and Fetch API are, let's compare them in detail based on various criteria. This will help us identify their strengths and weaknesses. However, before we do that, let's present a brief table with their main aspects:

Parameter

Fetch

Axios

Installation

Built-in in most modern browsers

Requires installation through NPM/Yarn

Browser Compatibility

Supported by most modern browsers, but requires polyfills for IE

Supported by all modern browsers and IE

JSON Handling

Requires calling .json() on the response

Automatically transforms JSON to/from objects

Error Handling

Does not reject promises for HTTP error responses

Automatically rejects promises for HTTP error responses

Timeouts

No built-in support

Supports timeouts out of the box

Download Progress

Not natively supported

Supports download progress tracking

CORS (Cross-Origin Resource Sharing)

Supported

Supported

CSRF/XSRF Protection

No built-in support

Built-in support

Interceptors

Not supported

Supported

Default Configuration

Limited support

Easily configurable global settings

Node.js Usage

Requires additional libraries for Node.js

Supported out of the box

Library Size

Smaller (built into browsers by default)

Larger (due to additional features)

Promises & async/await

Easily used with promises and async/await

Requires chaining with .then() or using async/await

Built-in Methods

Directly uses browser's built-in methods (Headers, Request, Response)

Requires axios.get(), axios.post(), etc.

Global Settings

Utilizes browser's global settings (e.g., headers, caching)

Easily configurable global settings

Convenience in Browser

Native browser API, simplifying debugging in DevTools

May require source maps for debugging in DevTools

Technology

ES6+ standard

Library, not part of the JavaScript standard

As you can see, each of them has both pros and cons, which can make choosing the right tool a bit difficult. To determine the best tool, let's take a closer look at each of them and provide relevant code samples for different situations.

Explore our Scraping Packages & Libraries

The Node.js Google Maps Scraping Library empowers developers to extract comprehensive location information from Google Maps effortlessly. This library streamlines…

The Google SERP API library is a comprehensive solution that allows developers to integrate Google Search Engine Results Page (SERP) data. It provides a simplified…

Syntax and Response object

The Fetch API is a native JavaScript feature, eliminating the need for external libraries making it a convenient choice. While we've covered GET requests, a POST request will better illustrate the differences between Fetch API and Axios. Here's how a POST request would look like with fetch():

fetch('https://example.com', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    key1: 'value1',
    key2: 'value2',
  }),
})
  .then(response => {
    if (!response.ok) {
        throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('There was a problem with your fetch operation:', error));

On the other hand, Axios is an external library that provides a more concise and convenient syntax. Therefore, the same request using it will look much simpler and shorter:

axios.post('https://example.com', {
    key1: 'value1',
    key2: 'value2',
  })
  .then(response => console.log(response.data))
  .catch(error => console.error('There was a problem with your axios operation:', error));

As the examples demonstrate, Axios can help reduce the amount of code and make it easier to read. Therefore, many developers prefer it due to its readability and ease of use.

Performance considerations

Comparison of Axios and the Fetch API in terms of performance depends on specific use cases and project requirements. In general, fetch() has advantages in terms of lightweight design and integration with native browser capabilities, whereas Axios provides additional conveniences that can be beneficial in certain scenarios.

Axios introduces some overhead due to its additional functionality, making it heavier compared to fetch(). Moreover, interceptors can incur additional costs in processing requests and responses, especially when using a large number of interceptors. However, Axios offers request caching functionality, which can enhance performance in scenarios with repetitive requests.

On the other hand, Fetch API is more lightweight and natively integrated into browsers, reducing the amount of downloaded code. Additionally, it uses promises, ensuring a clean and convenient syntax, as well as good performance in asynchronous scenarios. Furthermore, Fetch API  is, by default, integrated into native browser capabilities such as Service Workers, which can be crucial for performance in modern web applications.

Therefore, if you need to perform a simple HTTP request without additional features, fetch() may be the preferred option due to its lightweight nature. However, if additional features like interceptors and caching are necessary, or if you need to make HTTP requests in Node.js where fetch() is not part of the standard library, then Axios would be the better choice.

Response Timeout

Unfortunately, the Fetch API does not offer a direct way to set a timeout. However, you can use the AbortController and AbortSignal mechanisms to manually cancel a request after a certain amount of time has passed.

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);

fetch('https://example.com/', { signal: controller.signal })
  .then(function (response) {
    clearTimeout(timeoutId);
    return response.json();
  })
  .then(function (data) {
    console.log(data);
  })
  .catch(function (error) {
    if (error.name === 'AbortError') {
      console.log('Request canceled due to timeout');
    } else {
      console.log(error);
    }
  });

Axios allows you to set a timeout for requests using the timeout option in the request configuration. This option specifies the maximum amount of time (in milliseconds) that a request should take to complete. If the timeout is exceeded, the request will be aborted, and the promise will be rejected.

axios.get('https://example.com', { timeout: 5000 })
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    if (axios.isCancel(error)) {
      console.log('Request canceled due to timeout');
    } else {
      console.log(error);
    }
  });

Both solutions offer similar functionality, but Axios provides a more straightforward and convenient way to manage request timeouts.

Error Handling

Fetch API considers any HTTP status codes other than 200 (success) as an error. However, this is not automatic, and you need to check the status of your code to handle errors manually. Additionally, fetch() does not handle network errors (such as no internet connection or inability to establish a connection). To handle such errors, you will have to use try-catch around the fetch() call.

try {
    const response = await fetch('https://example.com');
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Fetch error:', error);
  }

Axios automatically handles HTTP statuses and triggers the catch block for all responses with error HTTP statuses (except 2xx). This simplifies error handling and allows you to focus on your code. Additionally, Axios easily handles network errors, such as no connection or inability to establish a connection.

axios.get('https://example.com')
  .then(response => console.log(response.data))
  .catch(error => {
    if (error.response) {
      console.error('Axios error! HTTP status:', error.response.status);
    } else if (error.request) {
      console.error('Axios error! Network issue:', error.message);
    } else {
      console.error('Axios error!', error.message);
    }
  });

Axios offers a more convenient and focused error-handling mechanism, especially in the context of HTTP statuses. In contrast, the fetch() requires more manual handling, particularly when dealing with network errors.

Upload Progress

Monitoring file upload progress with Axios is more straightforward and simpler than with the fetch(). Axios provides the onUploadProgress parameter, which automatically triggers whenever the upload progress updates. This simplifies progress monitoring and integration with your code to display upload information.

const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

const fileStream = fs.createReadStream('file.txt');
const formData = new FormData();
formData.append('file', fileStream);

axios.post('https://example.com/', formData, {
  headers: formData.getHeaders(),
  onUploadProgress: progressEvent => {
    console.log(`Uploaded ${progressEvent.loaded} bytes`);
  }
})
.then(response => {
  console.log('Upload successful');
})
.catch(error => {
  console.error('Upload failed:', error);
});

Tracking download progress with the Fetch API is more complex and requires deeper integration with the response data stream. Manual extraction of progress information from the stream and its processing in the corresponding handler is necessary.

const file = document.querySelector('input[type="file"]').files[0];
const formData = new FormData();
formData.append('file', file);

fetch('https://example.com/', {
  method: 'POST',
  body: formData
}).then(response => {
  const reader = response.body.getReader();
  const contentLength = +response.headers.get('Content-Length');

  let loaded = 0;
  reader.read().then(function processResult(result) {
    if (result.done) {
      console.log('Upload completed');
      return;
    }

    loaded += result.value.length;
    console.log(`Uploaded ${loaded} of ${contentLength} bytes`);

    return reader.read().then(processResult);
  });
}).catch(error => {
  console.error('Upload failed:', error);
});

So, if your application heavily relies on file uploading, Axios can significantly simplify this functionality.

Backward-Compatibility

Fetch API is supported by most modern browsers but not by Internet Explorer and older versions of other browsers. Polyfills are required to ensure backward compatibility with outdated browsers.

Axios provides better backward compatibility because it can be used in browsers and Node.js without additional polyfills. This makes it a preferable choice for projects that require support for legacy browsers or environments.

Automatic JSON Data Transformation

The Fetch API does not automatically parse JSON responses. To get the data in JSON data format, you need to call the .json() method on the response object.

fetch('https://example.com/')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Axios offers automatic JSON data parsing. The response data is automatically extracted from the Axios response object and is accessible through the .data property.

axios.get('https://example.com/')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));

However, it is worth noting that Axios will try to convert the response to JSON automatically, even if the server returns data in a different format. If the server returns data in a format that cannot be converted to JSON (e.g., plain text, HTML, or XML), Axios will generate an error. But if you know the response format in advance and want to process it manually, you can use other Axios methods, such as .text() or .arrayBuffer(), to get the data in the desired format.

Explore our Scraping Packages & Libraries

Zillow API Node.js is a programming interface that allows developers to interact with Zillow's real estate data using the Node.js platform. It provides a set of…

Shopify API Node.js framework can be used to create custom eCommerce solutions, integrate Shopify functionality into existing applications, and automate various…

HTTP Interceptors

HTTP Interceptors, in the context of HTTP requests, are a mechanism that allows you to intercept and process requests and responses before they are sent or after they are received. It is a powerful tool used for:

  1. Adding common logic: You can add common logic to all HTTP requests, such as authentication, authorization, or logging.
  2. Error handling: You can handle errors centrally and provide a consistent user experience.
  3. Data manipulation: You can manipulate the request or response data before it is sent or received.
  4. Other operations: You can perform other operations, such as caching or logging, on HTTP requests and responses.

The Fetch API in the browser provides a Request object that can be used to create a request. However, the fetch() does not provide a built-in mechanism to intercept HTTP requests. This means that you need to explicitly handle Request and Response objects in your code to manipulate requests and responses.

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Axios provides a built-in HTTP interceptor mechanism. You can add interceptors for both requests and responses. This makes it easy to add common logic or data transformation for all requests.

const axios = require('axios');

axios.interceptors.request.use(config => {
  console.log('Request Interceptor:', config);
  return config;
}, error => {
  return Promise.reject(error);
});

axios.interceptors.response.use(response => {
  console.log('Response Interceptor:', response);
  return response;
}, error => {
  return Promise.reject(error);
});

axios.get('https://example.com/')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));

Axios simplifies adding common logic to all requests. It eliminates the need to explicitly handle requests and responses, making it a good choice for those who prefer to use full-fledged interceptors.

Download Progress

Fetch API and Axios provide different approaches for tracking download progress. fetch() provides a Response object that has a body.getReader() method. This method returns a ReadableStream object that can be used to read data in chunks, which allows you to track the progress.

fetch('https://example.com/')
  .then(response => {
    const contentLength = response.headers.get('Content-Length');
    const total = parseInt(contentLength, 10);
    let loaded = 0;
    const reader = response.body.getReader();

    function read() {
      return reader.read().then(({ done, value }) => {
        if (done) {
          console.log('Download complete');
          return;
        }
        loaded += value.byteLength;
        console.log(`Progress: ${(loaded / total) * 100}%`);
        return read();
      });
    }

    return read();
  })
  .catch(error => console.error('Download error:', error));

Axios, on the other hand, provides an onDownloadProgress callback function that can be used to track the download progress. This function is called periodically with information about the total number of bytes downloaded and the total number of bytes expected to be downloaded.

const axios = require('axios');
const url = 'https://example.com/';

axios({
  method: 'get',
  url: url,
  responseType: 'stream',
  onDownloadProgress: progressEvent => {
    const total = progressEvent.lengthComputable ? progressEvent.total : -1;
    const loaded = progressEvent.loaded;
    if (total !== -1) {
      console.log(`Progress: ${(loaded / total) * 100}%`);
    }
  },
})
  .then(response => {
    console.log('Download complete');
  })
  .catch(error => console.error('Download error:', error));

Which approach you use depends on your specific needs. If you need to track the progress of the download very precisely, then you should use the body.getReader() method. However, if you just need a general indication of the progress, then the onDownloadProgress callback function is a simpler option.

Simultaneous Requests

Both Fetch API and Axios support concurrent requests, but there are some differences in their usage and capabilities. Fetch API provides a basic mechanism for performing concurrent requests through promise.all.

const urls = ['https://example.com/data1', 'https://example.com/data2'];

const requests = urls.map(url => fetch(url));

Promise.all(requests)
  .then(responses => Promise.all(responses.map(response => response.json())))
  .then(data => console.log(data))
  .catch(error => console.error(error));

Axios provides the axios.all method for making simultaneous requests and axios.spread for distributing data across responses:

const axios = require('axios');

const urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];

const requests = urls.map(url => axios.get(url));

axios.all(requests)
  .then(axios.spread((...responses) => {
    const data = responses.map(response => response.data);
    console.log(data);
  }))
  .catch(error => console.error(error));

If concurrent requests are an important aspect for you and you need a more convenient syntax, Axios may be a preferable choice.

Handling CORS

The Fetch API is a standard part of browser JavaScript, which is convenient, but it requires more explicit management of CORS (Cross-Origin Resource Sharing) requests. On the other hand, Axios provides more convenient tools for working with CORS, automatically handling headers and providing options for additional configuration.

Community support and popularity

The fetch() is a standard built into modern browsers, so support and questions are usually discussed within the web development community. Moreover, the Fetch API documentation is extensive and provided by the Mozilla Developer Network (MDN), making it a reliable source of information. However, some problems and vulnerabilities that users have encountered have either been ignored for a long time or have not been resolved.

On the other hand, Axios has an active and constantly updated repository on Github, as well as a large community of users and developers. There are many discussions and questions on platforms like Stack Overflow. Therefore, discovered problems and vulnerabilities are fixed much faster.

Choosing Between Fetch and Axios

Now that we have looked at the different options and functionality provided by Axios and the Fetch API, we can discuss which tool is more suitable for different cases. However, it is worth noting that there is no one-size-fits-all answer to the question of which tool is better, as it depends on many factors, including the goals of the project and the skills of the programmer.

When to use Fetch

The Fetch API offers a convenient and lightweight way to perform HTTP requests in modern browsers. Its simplicity and use of promises make it the preferred choice for simple requests. However, some limitations, such as lack of support in older browsers and some shortcomings in error handling, may require the use of additional workarounds or alternative libraries in more complex scenarios.

Nevertheless, if the limitations of the fetch() are not a concern for your use case or you can work around them, it is preferable to use it because it is more reliable, already built into browsers, and has less impact on performance.

When to use Axios

If you're using NodeJS and need more functionality than the fetch(), or if you find it difficult to use, Axios is a better option. It's also a good choice for beginners, as it provides more functionality and simplifies coding.

Conclusion and Takeaways

Axios and Fetch API are both popular HTTP request libraries for JavaScript. Both have their own advantages and disadvantages, making it difficult to say definitively which one is better. The best choice for you will depend on your project's specific requirements, development preferences, and required functionality. In short, If you're new to JavaScript, start with Axios for its simplicity. For more control and performance, consider fetch() once you're more comfortable with the language. Another way is to use them both for different tasks.

Axios provides a convenient API for making HTTP requests and handling responses, including promise support, which makes it a popular choice among developers for working with HTTP in JavaScript. Fetch API was originally designed for use in browsers, but it can also be used in other environments, such as Node.js, with the help of polyfills or external libraries. It is more lightweight but also more complex.

So, if you require simplicity and are using only basic HTTP functions, fetch() might be the better option. However, for more complex scenarios where features like timeouts, automatic data transformation, and enhanced error handling are needed, Axios provides richer functionality.

Tired of getting blocked while scraping the web?

Try out Web Scraping API with proxy rotation, CAPTCHA bypass, and Javascript rendering.

  • 1,000 Free API Credits
  • No Credit Card Required
  • 30-Day Trial
Try now for free

Collect structured data without any coding!

Our no-code scrapers make it easy to extract data from popular websites with just a few clicks.

  • CSV, XLSX, and JSON Formats
  • No Coding or Software Required
  • Save Time and Effort
Scrape with No Code
Valentina Skakun

I'm a technical writer who believes that data parsing can help in getting and analyzing data. I'll tell about what parsing is and how to use it.