How to master HTTP requests with Axios

Learn how to use Axios for all your HTTP requests

Feature Image

Axios is one of the favorite HTTP clients among Javascript developers. It is used to send HTTP requests, especially AJAX requests, from the client-side as well as the server-side.

Sending HTTP requests from the Javascript side is now almost a necessity when developing dynamic web applications. Axios simplifies this task by providing an easy-to-use abstraction over Javascript’s XMLHttpRequest interface with a number of user-friendly functions and configuration options.

In this tutorial, we are going to walk through everything you need to know about sending HTTP requests with Axios with code examples and simplified explanations.

Let’s start our introduction with this question.


Why You Should Choose Axios?

To answer this question, let’s take a look at the Axios alternatives available for developers.

Javascript provides a built-in interface, XMLHttpRequest, to handle HTTP requests. However, sending requests with this interface is not very straightforward and takes too many lines of code to write.

If you have used JQuery, you must be familiar with the $_ajax function. It provides a simpler and easier-to-use abstraction over the XMLHttpRequest interface which we can use to send HTTP requests with fewer lines of code. But as libraries like JQuery became obsolete in the past few years, developers needed a native Javascript solution to create HTTP requests.

Now, Fetch API and Axios are the two most popular solutions in native Javascript that are used to send these requests. When compared to Fetch API, however, Axios has an advantage due to some of the unique features it provides to developers. Here we have listed a few of them.

  • Support for request and response interception
  • Ability to cancel requests
  • Support for older browsers (Internet Explorer 11)
  • Automatic transformation of JSON data
  • Client-side support for XSRF protection

Because of its powerful set of features, developers are now starting to prefer Axios over Fetch API to send HTTP requests.


Install Axios

You can install and use Axios on both the frontend and backend. The installation is simple if you are using a package manager like npm.

npm install axios

If you are using a content delivery network (CDN), embed the Axios script in HTML.

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

Or,

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

Send HTTP Requests with Axios

Sending HTTP requests with Axios is as simple as passing an object containing all the configuration options and data to the axios() function.

axios({
    method: "post",
    url: "/users",
    data: {
        username: "sam123",
        firstname: "sam",
        lastname: "smith"
    }
});

Let’s take a closer look at the configuration options used here.

  • method: The HTTP method the request must be sent in
  • url: The URL of the server the request must be sent to
  • data: In the case of POST, PUT, and PATCH requests, the data provided with this option are sent in the body of the HTTP request.

To see all the configuration options available with Axios request functions, refer to its official documentation .


Dedicated Request Functions

Other than the generic axios() function, Axios provides dedicated functions to simplify sending different types of requests. Follows is a list of those functions.

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]])

For example, we can use the axios.post() function to send POST requests instead of using the axios() function by setting the method to “post”.

axios.post("/users", {
    username: "sam123",
    firstname: "sam",
    lastname: "smith"
});

We can use the axios.get() function to send GET requests in a similar manner.

axios.get("/users", {
    params: {
        firstname: "sam"
    }
});

The params config option is used to set query parameters in the URL.

Send Multiple Concurrent Requests

We can use Axios to send multiple requests concurrently. To achieve this, we have to pass an array of request calls to the Promise.all() function.

Promise.all([
    axios.get("/users/sam123"),
    axios.get("/users/sam123/comments")
]);

Handle Responses with Axios

When we send an HTTP request to a remote server, we receive a response from that server containing certain information. We can retrieve this response using Axios.

According to Axios documentation, the returned response contains the following information.

{
  // `data` is the response that was provided by the server
  data: {},

  // `status` is the HTTP status code from the server response
  status: 200,

  // `statusText` is the HTTP status message from the server response
  statusText: 'OK',

  // `headers` the HTTP headers that the server responded with
  // All header names are lower cased and can be accessed using the bracket notation.
  // Example: `response.headers['content-type']`
  headers: {},

  // `config` is the config that was provided to `axios` for the request
  config: {},

  // `request` is the request that generated this response
  // It is the last ClientRequest instance in node.js (in redirects)
  // and an XMLHttpRequest instance in the browser
  request: {}
}

Since Axios is promise-based, the response is returned as a promise. So we need to use then() and catch() functions to retrieve the response and catch errors if there are any.

Let’s see how we can handle the response returned by a POST request.

axios.post("/users", {
    username: "sam123",
    firstname: "sam",
    lastname: "smith"
    })
    .then(response => {
        console.log(response);
        console.log(response.data);
        console.log(response.data.userId);
        console.log(response.status);
        console.log(response.statusText);
    })
    .catch(error => {
            console.log(error.message);
    });

Use async/await

We can also use async/await to send HTTP requests and handle responses instead of promises.

async function getUserData() {
    try {
        const response = await axios.get("/users/sam123");
        console.log(response);
    }
    catch (error) {
        console.log(error);
    }
}

Handle Responses from Concurrent Requests

In the previous section, we used Promise.all() method to send multiple concurrent requests. When all the requests passed to the method are completed, it returns a single promise with response objects of every request. We can separate the responses using the index of each request in the array passed to the method.

Promise.all([
    axios.get("/users/sam123"),
    axios.get("/users/sam123/comments")
    ])
    .then(response => {
       const user = response[0].data
       const comments = response[1].data
    })
    .catch(error => {
        console.log(error);
    });

Handle Errors

If an error occurs when sending an HTTP request with Axios, the returned error object contains specific information to help us figure out where exactly the error occurred. As you will see in the following example, there are three places where errors could occur.

axios.post("/users", {
    username: "sam123",
    firstname: "sam",
    lastname: "smith"
    })
    .then(response => {
        console.log(response);
    })
    .catch(error => {
        if (error.response) {
            //The response status is an error code
            console.log(error.response.status);
        }
        else if (error.request) {
            //Response not received though the request was sent
            console.log(error.request);
        }
        else {
            //An error occurred when setting up the request
            console.log(error.message);
        }
    });

With this information Axios provides, you can handle the errors appropriately based on the places they occurred at.


Send Data with POST Requests

When sending POST requests (also PUT and PATCH requests) with Axios, note how we pass a normal Javascript object as data. Axios converts this Javascript data to JSON by default. It also sets the “content-type” header to “application/json”.

However, if you pass a serialized JSON object as data, Axios treats the content type as “application/x-www-form-urlencoded” (form-encoded request body). If the intended content type is JSON, you have to manually set the header using the “headers” config option.

const data = JSON.stringify({name: "sam"});
const options = {
    headers: {"content-type": "application/json"}
}

axios.post("/users", data, options);

If you want to send any other type of data except JSON, you’d have to explicitly convert the data and set the content-type headers appropriately. Axios provides two config options, transformRequest and transformResponse, where you can carry out this conversion before sending a request and receiving a response, respectively.


Transform Data

Let’s see how we can use these two config options when sending requests.

axios({
    method: "post",
    url: "users/sam123",
    data: {
        username: "sam123",
        firstname: "sam",
        lastname: "smith"
    },
    transformRequest: [(data, headers) => {
        //Transform request data as you prefer

        return data;
    }],
    transformResponse: [(data) => {
        //Transform the response data as you prefer

        return data;
    }]
});

Set Custom Headers for Requests

You can easily set custom headers for the requests you are sending with Axios. You only have to pass an object containing the custom headers to the request method you are using.

const options = {
    headers: {"X-Custom-Header": "value"}
}

axios.get("users/sam123", options);

Set Config Defaults

You can set default config options so that they are applied to every request you send using Axios. This way, you don’t have to repeatedly set the options that are common to all requests.

For example, if you want to set the base URL or an authorization header used for every request, it can be easily achieved as the following example shows.

axios.defaults.baseURL = "https://example.com";
axios.defaults.headers.common["Authorization"] = AUTH_TOKEN

Set Config Defaults of Instances

Sometimes, setting default configurations for every HTTP request becomes unrealistic due to the differences in requests we send: we could be sending requests to two different APIs or with different authorization tokens depending on the user permissions.

In such cases, though we are not able to find config options common to every request, we might be able to find options common to different groups of requests. Axios provides us a way to set default configs for these different groups separately.

It’s by creating instances.

We can create separate instances and set default configs for each instance. Then, we can use this instance object to send requests instead of the axios object.

//Create new instance
const instance = axios.create();

//Set config defaults for the instance
instance.defaults.baseURL = "https://example.com";
instance.defaults.headers.common["Authorization"] = AUTH_TOKEN;

//Send requests using the created instance
instance.get("/users", {
    params: {
        firstname: "sam"
    }
});

Intercept Requests

HTTP request interception is one of the most interesting features in Axios. It allows you to intercept requests sent by and requests received to your program and carry out some common tasks before the operation is complete. This feature simplifies handling background tasks related to HTTP requests such as logging, authentication, and authorization.

Defining an interceptor for either requests or responses is a simple task.

axios.intercept.request.use(config => {
    //Intercept the request and do something before it is sent
    console.log("Request sent");
    return config;
}, error => {
    return Promise.reject(error);
});

axios.get("/users/sam123")
    .then(response => {
        console.log(response.data);
    });

Here, the config object is the exact config object we pass the axios function or one of its aliases. So the interceptor has full access to the request config and its data.

After setting the request interceptor, every time a new request is sent by the program, the message, “Request sent” is logged to the console.

We can set a response interceptor in a similar way.

axios.intercept.response.use(config => {
    //Intercept the response and do something when it is received
    console.log("Response recieved");
    return config;
}, error => {
    return Promise.reject(error);
});

axios.get("/users/sam123")
    .then(response => {
        console.log(response.data);
    });

Now, every time a response is received, the message, “Response received”, is logged to the console.

We can define interceptors for instances instead of the axios object as well.

instance.intercept.request.use(config => {
    //Intercept the request and do something before it is sent
    console.log("Request sent");
    return config;
}, error => {
    return Promise.reject(error);
});

Cancel Requests

Another interesting feature Axios provides is the ability to cancel requests whenever we prefer.

There are some cases in web development where we might find the response from the remote server to our request is no longer important. In such cases, we can save the system resources by simply canceling the request. And Axios provides us a method to do just that.

If you want to cancel a certain request, it should have a cancel token that was created at the time the request was created. We can use this token to cancel the request whenever we want.

This is how the canceling process is implemented.

const cancelToken = axios.cancelToken;
const source = cancelToken.source();

axios.get("/users/sam123", {
    cancelToken: source.token  //create cancel token
    })
    .then(response => {
        console.log(response.data);
    })
    .catch(thrown => {
        if (axios.isCancel(thrown)) {
            console.log("Request cancelled", thrown.message);
        }
        else {
            //handle the error
        }
    })

//Cancel the request
source.cancel("Request cancelled by the user");

It’s important to note that we can use a single source object to cancel several requests at the same time. All the requests whose cancel tokens are created using the given source are canceled when source.cancel is called.


Protect Against XSRF Attacks

Cross-site request forgery (XSRF) is a technique used by attackers to infiltrate web applications and carry out malicious tasks. In these attacks, the attacker disguises as a trusted user and tricks the application to execute actions for their benefit.

This could compromise the privacy and security of the user and even result in the attacker gaining access to the entire system if the user has high-level permission.

Axios provides a way to prevent such attacks by embedding additional authentication information when creating the request. This is how it is implemented.

const options = {
  xsrfCookieName: 'XSRF-TOKEN',
  xsrfHeaderName: 'X-XSRF-TOKEN',
};

axios.post("/users", options);

Summary

In this tutorial, we discussed everything you need to know about sending HTTP requests with Axios as a web developer. As you would have seen, Axios makes the task of handling HTTP requests and responses incredibly simple.

It provides a number of configuration options to alter the default behavior according to our needs. It provides a number of methods to simplify the task of sending HTTP requests. With the help of Axios, you can implement HTTP request sending features in either backend and frontend of your application faster than you’d have imagined.

So if you are not already, add Axios to your group of Javascript libraries and easily implement your HTTP request sending tasks with it.

Join more than a thousand developers!

Subscribe now to our free, weekly e-mail with the best new articles, courses, and special bonuses.

We won't send you spam. Unsubscribe at any time.