59

Studied the documentation of axios and of ES6 fetch I found than both are quite similar and have experienced a strong influence of $.ajax and its shorthands.

Main advantage of axios is browser support.

So am I right that if I use babel-polyfill - there is no reasons to use axios?

Sasha Kos
  • 2,480
  • 2
  • 22
  • 37
  • 1
    There's a bunch of reasons to use Axios. Fetch feels like low-level API that weren't designed to be comfortable and lacks a lot of features that Axios has - interceptors, cancellation, testability... This includes most of those that can be seen on Axios page, https://github.com/axios/axios#features The question is off-topic. Just try both in action and see yourself. A single fetch advantage that can be noted is that it seamlessly works with service workers because it returns Response object (it isn't too convenient in other cases). – Estus Flask May 10 '18 at 16:49
  • A link from deleted answer that may help, https://medium.com/@thejasonfile/fetch-vs-axios-js-for-making-http-requests-2b261cdd3af5 – Estus Flask May 10 '18 at 16:54
  • Axios is for the lazy and uninitiated. – morganney Feb 11 '23 at 17:25

3 Answers3

59

A few reasons for using Axios over Fetch:

  1. Ability to monitor request progress

This is more of a question between XMLHttpRequest (which powers axios) or Fetch API.

Fetch API currently does not provide any way to get notified of the request progress, a feature which powers feedback mechanism for large file uploads for example.

Axios, on the other hand, has this functionality built in:

axios.post('/api', data, {
    onUploadProgress: ({ total, loaded }) => {
        // update progress
    }),
})
  1. Error handling

When your backend returns 500 Internal Server Error response code, fetch will not treat it any different from 200 OK.

This is an inconvenience in most cases since all your previous assumptions of what a response would look like are no longer valid.

Most often, when receiving an erroneous response from the server you'd want to abort the processing pipeline as soon as possible, and switch to an error handling case.

fetch(url)
    .then(reponse => {
        if (!(status >= 200 && status < 300)) {
            return Promise.reject(new Error("Invalid response status"));
        }

        return response;
    })
    .then(response => response.json())
    .then(/* normal processing */)
    .catch(/* error handling */);

This is not hard to accomplish, but you'd probably want to capture this logic under some abstraction to avoid repetition, and this brings us one step closer to Web API abstraction which is Axios.

Axios does a sane thing and rejects the promise if the response returns erroneous status. This behavior is customizable as are most of the things with axios.

  1. Testing

Axios has moxios, fetch has fetch-mock.

Both of those libraries are great but in my experience, fetch-mock required additional setup to get Jest to use mocked fetch over polyfilled one.

I also like that moxios.wait() returns a promise which will be resolved after matching the request.

  1. Other features that Axios offers

For example, you can configure an interceptor which will add api key to all request parameters, or monitor active requests to show a loading screen.


Reasons for using one option over the other may vary from actual requirements to convenience.

If you need to monitor progress, use Axios (or XMLHttpRequest).

If you are writing a service worker, use Fetch.

Otherwise, use what's more convenient to you.

mpontus
  • 2,143
  • 2
  • 19
  • 21
  • 8
    "If you are writing a service worker, use Fetch." - for anyone wondering, it seems that Axios relies on `XMLHttpRequest`, but this API has been deprecated in favour of `Fetch` and service workers only support `Fetch`. There are plans in the future to switch Axios to use `Fetch`: https://github.com/axios/axios/issues/484 – harvzor Nov 07 '18 at 16:37
  • 1
    @Harvey not deprecated. – atilkan Feb 27 '19 at 10:50
  • 2
    @atikan Oops. Use of `XMLHttpRequest` is perhaps discouraged, but will never be deprecated. – harvzor Feb 27 '19 at 22:33
  • Another difference is the ease of setting timeouts using Axios: `axios({ method: 'post', url: '/login', timeout: 4000, data: { firstName: 'Patrick', lastName: 'Bateman' } })`. HTTP Interceptor implementations is also worth looking into further – bmd Mar 09 '21 at 16:39
  • Fetch can use the Abort Controller API to cancel requests. Also progress is coming. https://developer.mozilla.org/en-US/docs/Web/API/AbortController https://javascript.info/fetch-progress – rajakvk Nov 04 '21 at 14:22
36

This:

fetch('https://jsonplaceholder.typicode.com/posts', {
    method: 'POST',
    body: JSON.stringify({
      title,
      body
    })
  }).then((res) => {
    if (res.ok) {
      return res.json()
    }

    throw new Error(res.responseText);

  })
  .then((data) => console.log(data))
  .catch((err) => console.log(err))

can essentially be expressed by axios with this:

axios.post('https://jsonplaceholder.typicode.com/posts', {
    title,
    body
  }).then((data) => console.log(data))
  .catch((err) => console.log(err))

So in essence:

  1. No need to do res.json(), res.text() etc
  2. No need to handle res.ok in order to catch non 200 status errors in actual promise catch handler.
  3. No need to stringify payload, it's handled by axios by default.

Overall axios provides a more higher level and simple api to work with requests.

Karen Grigoryan
  • 5,234
  • 2
  • 21
  • 35
3

Axios is an NPM library and therefore works on both Node.js and the browser. fetch is a Web API and is not available to Node. Conversely, Node.js has the http module and does not have the Fetch API. It also simplifies passing data and handling different types of HTTP Requests

Meghan
  • 1,215
  • 11
  • 17
  • There npm libraries that implement the `fetch` API too. – loganfsmyth May 10 '18 at 17:04
  • 3
    Ok, but when used on Node, it doesn't use a built-in function called `fetch`. It's a polyfill – Meghan May 10 '18 at 17:07
  • 3
    Totally, but if it follows the spec, it's still the fetch API whether it is in a browser, or Node. – loganfsmyth May 10 '18 at 17:19
  • 1
    @Meghan I found your insight "`fetch` is a polyfilled on Node" to be critical, because I stumbled into issues with `fetch` on Node, that were not reproducible in browser-fetch. So thank you! – Robert Jan 19 '22 at 11:24
  • 1
    FYI, `fetch()` is coming to Node. It's already an experimental feature in Node `v17.5`, enabled with `--experimental-fetch`. – m4heshd Mar 20 '22 at 17:55