Skip to content
Search

Axios

lastmod 2025-12-29created 2019-01-1426 edits

Promise based HTTP client for the browser and node.js

Categories

Interceptors

client.interceptors.response.use(res => {
  if (res.data.status === false) {
    // Error message is retrived from the JSON body.
    const error = new Error(res.data.message);
    // Attach the response instance, in case we would like to access it.
    error.response = res;

    throw error;
  }

  // If the status is true, simply return back the response instance.
  return res;
});

How to turn a Status Code into an error

Using the validateStatus config option, you can define HTTP code(s) that should throw an error.

axios.get('/user/12345', {
  validateStatus: function (status) {
    return status < 500; // Resolve only if the status code is less than 500
  }
})

Await request

async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

Simple example

Performing a POST request:

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    // always executed
  });

Performing multiple concurrent requests:

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

Promise.all([getUserAccount(), getUserPermissions()])
  .then(function (results) {
    const acct = results[0];
    const perm = results[1];
  });

When you want to skip Interceptors

axios.interceptors.response.use(undefined, err => {
  if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
    refreshLogin(getRefreshToken(),
      success => {
        setTokens(success.access_token, success.refresh_token)
        err.config.__isRetryRequest = true
        err.config.headers.Authorization = 'Bearer ' + getAccessToken()
        axios(err.config)
      },
      error => { console.log('Refresh login error: ', error) }
    )
  }
})

Personally, rather than adding a new Property to err.config, I prefer adding it to error.config.headers, since that doesn't break the type symbols. (Though there's no way to avoid sending that header to the server...)

Alternatively, use the same axios.create() to make a new instance. (In that case, when testing, you have to pass the instance to a mocking object like axios-mock-adapter for the tests to work properly,,, which isn't great either~;;;)

Form submission (application/x-www-form-urlencoded)

By default, axios serializes JavaScript objects to 'JSON'. To send data instead of in the application/x-www-form-urlencoded format, you can use one of the following options.

Browser

In a browser, you can use the URLSearchParams API as follows.

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

NOTE

URLSearchParams is not supported by all browsers, but there is a polyfill (url-search-params) available.

Alternatively, you can encode the data using the qs library.

const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));

If you are using ES6+, you can write it as follows.

import qs from 'qs';
const data = { 'bar': 123 };
const options = {
  method: 'POST',
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
  data: qs.stringify(data),
  url,
};
axios(options);

Node.js

You can use the querystring module as follows.

const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

Of course, you can also use the qs library.

const qs = require('qs');
axios.post('http://something.com/', qs.stringify({ foo: 'bar' }));

NOTE

The querystring method of Node.js has problems stringifying nested objects. If you often need to stringify nested objects, the qs library is recommended.

Parameter Serializer

The qs module makes this easy.

import axios from 'axios';
import qs from 'qs';

axios.defaults.baseURL = process.env.REACT_APP_BASE_URL || window.location.origin;
axios.defaults.headers.post['Accept'] = 'application/json';
axios.defaults.paramsSerializer = params => {
  return qs.stringify(params)
};

Renewing JWT Refresh tokens with Axios

let isTokenRefreshing = false;
let refreshSubscribers = [];

const onTokenRefreshed = (accessToken) => {
  refreshSubscribers.map((callback) => callback(accessToken));
};

const addRefreshSubscriber = (callback) => {
  refreshSubscribers.push(callback);
};

axios.interceptors.response.use(
  (response) => {
    return response;
  },
  async (error) => {
    const {
      config,
      response: { status },
    } = error;
    const originalRequest = config;
    if (status === 401) {
      if (!isTokenRefreshing) {
        // isTokenRefreshing이 false인 경우에만 token refresh 요청
        isTokenRefreshing = true;
        const refreshToken = await AsyncStorage.getItem("refreshToken");
        const { data } = await axios.post(
          `http://localhost:3000/refresh/token`, // token refresh api
          {
            refreshToken,
          }
        );
        // 새로운 토큰 저장
        const {
          accessToken: newAccessToken,
          refreshToken: newRefreshToken,
        } = data;
        await AsyncStorage.multiSet([
          ["accessToken", newAccessToken],
          ["refreshToken", newRefreshToken],
        ]);
        isTokenRefreshing = false;
        axios.defaults.headers.common.Authorization = `Bearer ${newAccessToken}`;
        // 새로운 토큰으로 지연되었던 요청 진행
        onTokenRefreshed(newAccessToken);
      }
      // token이 재발급 되는 동안의 요청은 refreshSubscribers에 저장
      const retryOriginalRequest = new Promise((resolve) => {
        addRefreshSubscriber((accessToken) => {
          originalRequest.headers.Authorization = "Bearer " + accessToken;
          resolve(axios(originalRequest));
        });
      });
      return retryOriginalRequest;
    }
    return Promise.reject(error);
  }
);

See also

Favorite site

References


  1. Maruzzings_devlog_-_axios_interceptors_token_refresh.pdf ↩

author Zer0 sitemap