Written by Faraz Kelhini✏️
Leveraging specialized tools for HTTP requests can make a difference in your day-to-day developer experience and productivity. In this tutorial, we'll demonstrate how to make HTTP requests using Axios in JavaScript with clear examples, including how to make an Axios request with the four HTTP request methods, how to send multiple requests simultaneously with Promise.all
, and much more.
TL;DR: What is Axios?
Axios is a simple, promise-based HTTP client for the browser and Node.js. It provides a consistent way to send asynchronous HTTP requests to the server, handle responses, and perform other network-related operations.
On the server side, Axios uses Node.js' native http
module, while on the browser, it uses XMLHttpRequest
objects.
Editor’s note: This blog was updated by David Omotayo in April 2025 to provide a clear and concise general overview of Axios, include practical use cases for Axios, and answer frequently asked questions regarding the HTTP client.
Why use Axios over Fetch?
The most common way for frontend programs to communicate with servers is through the HTTP protocol. You are probably familiar with the Fetch API and the XMLHttpRequest
interface, which allows you to fetch resources and make HTTP requests.
If you're using a JavaScript library, chances are it comes with a client HTTP API. jQuery's $.ajax()
function, for example, has been particularly popular with frontend developers. But as developers move away from such libraries in favor of native APIs, dedicated HTTP clients have emerged to fill the gap.
As with Fetch, Axios is promise-based. However, it provides a more powerful and flexible feature set.
Here are a few reasons some developers favor Axios:
- Request and response interception
- Streamlined error handling
- Protection against XSRF
- Support for upload progress
- Support for older browsers
- Automatic JSON data transformation
Getting started: Installing Axios
You can install Axios using the following command for npm, Yarn, and pnpm, respectively:
npm install axios
yarn add axios
pnpm add axios
To install Axios using a content delivery network (CDN), run the following:
<<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
After installing Axios, you can begin making HTTP requests in your application. This is as simple as importing the axios
function and passing a configuration (config) object to it:
import axios from "axios"
axios({
method: "",
url: "",
data: "",
responseType: "",
headers: {...},
timeout: "",
responseType: "",
})
These properties, except for the url
and method
properties (which are required in most cases), are optional. If not specified in the configuration, Axios will automatically set default values. The method
property accepts one of the four standard HTTP request methods: GET
, POST
, PUT
, and DELETE
, while the url
property accepts the URL of the service endpoint to fetch or send data from or to.
Making GET
requests with Axios
The GET
request method is the most straightforward. It’s used to read or request data from a specified resource endpoint.
To make a GET
request using Axios, you need to provide the URL from which the data is to be read or fetched to the url
property, and the string "get"
to the method
property in the config object:
// send a GET request
axios({
method: 'get',
url: 'api/items'
});
This code will fetch a list of items from the URL endpoint if the request is successful.
Making POST
requests with Axios
A POST
request is used to send data, such as files or resources, to a server. You can make a POST
request using Axios by providing the URL of the service endpoint and an object containing the key-value pairs to be sent to the server.
For a basic Axios POST
request, the configuration object must include a url
property. If no method property is provided, GET
will be used as the default.
Let's look at a simple Axios POST
example:
// send a POST request
axios({
method: 'post',
url: 'api/login',
data: {
firstName: 'Finn',
lastName: 'Williams'
}
});
This should look familiar to those who have worked with jQuery’s $.ajax
function. This code instructs Axios to send a POST
request to /login
with an object of key-value pairs as its data. Axios will automatically convert the data to JSON and send it as the request body.
Check out our article for more nuances on the POST request method in Axios.
PUT
and DELETE
requests in Axios
The PUT
and DELETE
request methods are similar to POST
in that they each send data to the server, albeit in a different way.
PUT
The PUT
request method is used to send data to a server to create or update a resource using the data provided in the request’s body.
To make a PUT
request using Axios, you need the resource's Uniform Resource Identifier (URI
), a URL with a query parameter that precisely identifies the location of a resource on the server, and the data payload to be sent to the server:
// Send a PUT request
const updatedItem = { name: 'Updated Item', price: 150 };
axios({
method: 'get',
url: 'https://api.example.com/items/1',
data: updatedItem
})
In this example, the updatedItem
data object will be sent to the location of a resource with an object Id
of 1
.
If the request is successful and an existing resource is found at the URI location, PUT
will replace it. If no existing resource is found, PUT
will create a new one using the provided payload data.
DELETE
The DELETE
request method also uses a URI's query parameter to identify and remove a resource from the server.
To make a DELETE
request using Axios, you need to pass the string "delete"
to the method
property and provide a URL with a query parameter in the url
property:
// Send a DELETE request
axios({
method: 'delete',
url: 'https://api.example.com/items/20',
})
If the request is successful, the resource or file with an id
of 20
will be removed from the server.
Shorthand methods for Axios HTTP requests
Axios also provides a set of shorthand methods for performing different types of requests. The methods include:
-
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, the following code shows how the previous POST
example could be written using the axios.post()
shorthand method:
axios.post('/login', {
firstName: 'Finn',
lastName: 'Williams'
});
Handling responses and errors
Once an HTTP request is made, Axios returns a promise that is either fulfilled or rejected, depending on the response from the backend service.
To handle the result, you can use the then()
method, like this:
axios.post('/login', {
firstName: 'Finn',
lastName: 'Williams'
})
.then((response) => {
console.log(response);
}, (error) => {
console.log(error);
});
If the promise is fulfilled, the first argument of then()
will be called; if the promise is rejected, the second argument will be called. According to the Axios documentation, the fulfillment value is an object containing the following properties:
{
// `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 headers that the server responded with
// All header names are lower cased
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 the browser
request: {}
}
As an example, here's how the response looks when requesting data from the GitHub API:
axios.get('https://api.github.com/users/mapbox')
.then((response) => {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});
// logs:
// => {login: "mapbox", id: 600935, node_id: "MDEyOk9yZ2FuaXphdGlvbjYwMDkzNQ==", avatar_url: "https://avatars1.githubusercontent.com/u/600935?v=4", gravatar_id: "", …}
// => 200
// => OK
// => {x-ratelimit-limit: "60", x-github-media-type: "github.v3", x-ratelimit-remaining: "60", last-modified: "Wed, 01 Aug 2018 02:50:03 GMT", etag: "W/"3062389570cc468e0b474db27046e8c9"", …}
// => {adapter: ƒ, transformRequest: {…}, transformResponse: {…}, timeout: 0, xsrfCookieName: "XSRF-TOKEN", …}
Error handling with Axios
An HTTP request may succeed or fail. Therefore, it is important to handle errors on the client side and provide appropriate feedback for a better user experience.
Possible causes of error in a network request may include server errors, authentication errors, missing parameters, and requesting non-existent resources.
Axios, by default, rejects any response with a status code that falls outside the successful 2xx range. However, you can modify this feature to specify what range of HTTP codes should throw an error using the validateStatus
config option, like in the example below:
axios({
baseURL: "https://jsonplaceholder.typicode.com",
url: "/todos/1",
method: "get",
validateStatus: status => status <=500,
})
.then((response) => {
console.log(response.data);
})
The error object that Axios passes to the .catch
block has several properties, including the following:
.catch(error => {
console.log(error.name)
console.log(error.message)
console.log(error.code)
console.log(error.status)
console.log(error.stack)
console.log(error.config)
})
In addition to the properties highlighted above, if the request was made and the server responded with a status code that falls outside the 2xx range, the error object will also have the error.response
object.
On the other hand, if the request was made but no response was received, the error object will have an error.request
object. Depending on the environment, the error.request
object is an instance of XMLHttpRequest
in the browser environment and an instance of http.ClientRequest
in Node.
You need to check for error.response
and error.request
objects in your .catch
callback to determine the error you are dealing with so that you can take appropriate action:
axios.get("https://jsonplaceholder.typicode.com/todos").catch(function (error) {
if (error.response) {
// Request was made. However, the status code of the server response falls outside the 2xx range
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// Request was made but no response received
console.log(error.request);
} else {
// Error was triggered by something else
console.log("Error", error.message);
}
console.log(error.config);
});
Handling API error responses with Axios interceptors
Sometimes, duplicating the code above in the .catch
callback for each request can become tedious and time-consuming. You can instead intercept the error and handle it globally like so:
axios.interceptors.request.use(null, function (error) {
// Do something with request error
return Promise.reject(error);
});
axios.interceptors.response.use(null, function (error) {
// Do something with response error
if (error.response) {
// Request was made. However, the status code of the server response falls outside the 2xx range
} else if (error.request) {
// Request was made but no response received
} else {
// Error was triggered by something else
}
return Promise.reject(error);
});
A more granular, centralized error-handling approach is maintaining the API globally and managing all response and request errors with a dedicated handler function.
Let’s understand it with a simple React app that shows toast messages when a request or response error occurs. Start by creating a file called api.js
in the src
directory of your React app and use the axios.create
method to create a custom Axios instance.
In this example, I'm using a placeholder API to demonstrate and use one of its endpoints as the base URL of our Axios instance:
// src/api.js
import axios from 'axios';
import toast from 'react-hot-toast';
// Create a custom Axios instance
const api = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com',
});
Next, let's define a handler function and call it handleError
in the same file. This function takes one argument — expected to be the error object when we implement this with Axios interceptors. With this error object, we can categorize errors based on their type (e.g., response, request, setup) and display appropriate user feedback using a React toast library:
// src/api.js
// Previous code...
// Centralized error handling
const handleError = (error) => {
/*
* If request was made, but the status code
* of the server response falls outside
* the 2xx range.
*/
if (error.response) {
// A lookup table of different error messages
const messages = {
404: 'Resource not found',
500: 'Server error. Please try again later.',
};
const errorMessage =
messages[error.response.status] || `Unexpected error: ${error.response.status}`;
toast.error(errorMessage, { id: 'api-error' });
console.error('Full error:', error);
return;
}
// If request was made but no response received
if (error.request) {
toast.error('No response from server. Check your network connection.', { id: 'api-error' });
console.error('Full error:', error);
return;
}
// If error was triggered by something else
toast.error('Error setting up the request', { id: 'api-error' });
console.error('Full error:', error);
};
Now, we can add a response interceptor to our custom Axios instance to provide automatic success notifications for successful API responses and delegate error handling to the handleError
function:
// src/api.js
// Previous code...
// Axios interceptor
api.interceptors.response.use(
(response) => {
const successMessage =
response.config.successMessage ||
`${response.config.method.toUpperCase()} request successful`;
toast.success(successMessage, {
id: 'api-success',
});
return response;
},
(error) => {
handleError(error);
return Promise.reject(error);
}
);
export default api;
We can then use this custom Axios instance in a component where we want to consume the API (the placeholder API in this case) and let it handle errors by itself. Here's the complete setup of our React app with HTTP error feedback following a centralized error-handling approach.
Using Axios with async
and await
The async
and await
syntax is syntactic sugar around the Promise API. It helps you write cleaner, more readable, and maintainable code. With async
and await
, your codebase feels synchronous and easier to think about.
When using async
and await
, you invoke axios
or one of its request methods inside an asynchronous function, like in the example below:
const fetchData = async () => {
try {
const response = await axios.get("https://api.github.com/users/mapbox");
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
} catch (error) {
// Handle error
console.error(error);
}
};
fetchData();
When using the async
and await
syntax, it’s standard practice to wrap your code in a try...catch
block. Doing so will ensure you appropriately handle errors and provide feedback for a better user experience.
Using Promise.all
to send multiple requests
You can use Axios with Promise.all
to make multiple requests in parallel by passing an iterable of promises to it. The Promise.all
static method returns a single promise object that fulfills only when all input promises have been fulfilled.
Here's a simple example of how to use Promise.all
to make simultaneous HTTP requests:
// execute simultaneous requests
Promise.all([
axios.get("https://api.github.com/users/mapbox"),
axios.get("https://api.github.com/users/phantomjs"),
]).then(([user1, user2]) => {
//this will be executed only when all requests are complete
console.log("Date created: ", user1.data.created_at);
console.log("Date created: ", user2.data.created_at);
});
// logs:
// => Date created: 2011-02-04T19:02:13Z
// => Date created: 2017-04-03T17:25:46Z
This code makes two requests to the GitHub API and then logs the value of the created_at
property of each response to the console. Keep in mind that if any of the input promises are rejected, the entire promise will immediately be rejected, returning the error from the first promise that encountered a rejection.
Sending custom headers with Axios
Sending custom headers with Axios is straightforward. Simply pass an object containing the headers as the last argument. For example:
const options = {
headers: {'X-Custom-Header': 'value'}
};
axios.post('/save', { a: 10 }, options);
Axios timeout settings
When making a network request to a server, it is not uncommon to experience delays when the server takes too long to respond. It is standard practice to timeout an operation and provide an appropriate error message if a response takes too long. This ensures a better user experience when the server is experiencing downtime or a higher load than usual.
With Axios, you can use the timeout
property of your config
object to set the waiting time before timing out a network request. Its value is the waiting duration in milliseconds. The request is aborted if Axios doesn't receive a response within the timeout duration. The default value of the timeout
property is 0
milliseconds (no timeout).
You can check for the ECONNABORTED
error code and take appropriate action when the request times out:
axios({
baseURL: "https://jsonplaceholder.typicode.com",
url: "/todos/1",
method: "get",
timeout: 2000,
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
if (error.code === "ECONNABORTED") {
console.log("Request timed out");
} else {
console.log(error.message);
}
});
You can also timeout a network request using the AbortSignal.timeout
static method. It takes the timeout as an argument in milliseconds and returns an AbortSignal
instance. You need to set it as the value of the signal
property.
The network request aborts when the timeout expires. Axios sets the value of error.code
to ERR_CANCELED
and error.message
to canceled
:
const abortSignal = AbortSignal.timeout(200);
axios({
baseURL: "https://jsonplaceholder.typicode.com",
url: "/todos/1",
method: "get",
signal: abortSignal,
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
if (error.code === "ERR_CANCELED" && abortSignal.aborted) {
console.log("Request timed out");
} else {
console.log(error.message);
}
});
Automatic object transformation
Axios automatically serializes JavaScript objects to JSON when making a POST
or PUT
request. This eliminates the need to serialize the request bodies to JSON.
Axios also sets the Content-Type
header to application/json
. This enables web frameworks to automatically parse the data:
// A sample JavaScript object to be sent using Axios
const data = {
name: 'Jane',
age: 30
};
// The `data` object will be automatically converted to JSON
axios.post('/api/users', data);
If you want to send a pre-serialized JSON string using a POST
or PUT
request, you'll need to make sure the Content-Type
header is set:
// A pre-serialized JSON string
const jsonData = JSON.stringify({
name: 'John',
age: 33
});
// Need to manually set Content-Type here
axios.post('/api/users', jsonData, {
headers: {
'Content-Type': 'application/json'
}
});
Transforming requests and responses
Although Axios automatically converts requests and responses to JSON by default, it also allows you to override the default behavior and define a different transformation mechanism. This is particularly useful when working with an API that accepts only a specific data format, such as XML or CSV.
To change request data before sending it to the server, set the transformRequest
property in the config object.
Note that this method only works for PU
T
, POST
, DELETE
, and PATCH
request methods.
Here's an example of how to use transformRequest
in Axios to transform JSON data into XML data and post it:
const options = {
method: 'post',
url: '/login',
data: {
firstName: 'Finn',
lastName: 'Williams'
},
transformRequest: [(data, headers) => {
// Convert to XML
const xmlData = `
${data.firstName}
${data.lastName}
`;
// Set the Content-Type header to XML
headers['Content-Type'] = 'application/xml';
return xmlData;
}]
};
// send the request
axios(options);
To modify the data before passing it to then()
or catch()
, you can set the transformResponse
property. Leveraging both the transformRequest
and transformResponse
, here’s an example that transforms JSON data to CSV, posts it, and then turns the received response into JSON to use on the client:
const options = {
method: 'post',
url: '/login',
data: {
firstName: 'Finn',
lastName: 'Williams'
},
transformRequest: [(data, headers) => {
// Convert to CSV
const csvData = `firstName,lastName\n${data.firstName},${data.lastName}`;
// Set the Content-Type header to CSV
headers['Content-Type'] = 'text/csv';
return csvData;
}],
transformResponse: [(data) => {
// If server responds with CSV, parse it
const rows = data.split('\n');
const headers = rows[0].split(',');
const values = rows[1].split(',');
return {
[headers[0]]: values[0],
[headers[1]]: values[1]
};
}]
};
// send the request
axios(options);
Intercepting requests and responses
HTTP interception is a popular feature of Axios. With this feature, you can examine and change HTTP requests from your program to the server and vice versa, which is very useful for a variety of implicit tasks, such as logging and authentication.
What are Axios interceptors?
Axios interceptors are functions that can be executed before a request is sent or after a response is received through Axios. There are two types of interceptor methods in Axios: request and response.
At first glance, interceptors look very much like transforms, but they differ in one key way: unlike transforms, which only receive the data and headers as arguments, interceptors receive the entire response object or request config.
You can declare a request interceptor in Axios like this:
// declare a request interceptor
axios.interceptors.request.use(config => {
// perform a task before the request is sent
console.log('Request was sent');
return config;
}, error => {
// handle the error
return Promise.reject(error);
});
// sent a GET request
axios.get('https://api.github.com/users/mapbox')
.then(response => {
console.log(response.data.created_at);
});
This code logs a message to the console whenever a request is sent and then waits until it gets a response from the server, at which point it prints the time the account was created at GitHub to the console. One advantage of using interceptors is that you no longer have to implement tasks for each HTTP request separately.
Axios also provides a response interceptor, which allows you to transform the responses from a server on their way back to the application. For example, here's how to catch errors in an interceptor with Axios:
// declare a response interceptor
axios.interceptors.response.use((response) => {
// do something with the response data
console.log('Response was received');
return response;
}, error => {
// handle the response error
return Promise.reject(error);
});
// sent a GET request
axios.get('https://api.github.com/users/mapbox')
.then(response => {
console.log(response.data.created_at);
});
Practical use cases for Axios
The use cases for Axios go beyond simply posting or fetching data from a server.
In real-world settings, data is often protected and requires authentication before access is granted, request progress may need to be monitored, and some requests might need to be canceled if they become redundant. These are all real-world use cases for which Axios in JavaScript provides simplified solutions.
Authenticated requests with Axios
Accessing protected data with Axios requires more than just providing a URL. The goal is to securely include credentials with your HTTP requests to authenticate with the server before being granted access to post or fetch data to and from the server.
Typically, you include either a JSON Web Token (JWT
) via the Authorization
header or base64-encoded credentials, depending on the authentication method, to make a protected request.
Bearer tokens
This is the most common authentication method in modern APIs. This method involves obtaining a token (JSON Web Token - JWT
) after a successful login and including this token in the Authorization
header of subsequent requests.
You can make protected requests with Axios using the bearer token method by adding a headers
option to the config object and passing the token to the Authorization
property:
axios.get('/api/protected-resource', {
headers: {
Authorization: `Bearer ${Token}`
}
});
Basic authentication
This authentication method uses a similar approach to the bearer token method, but it sends a base64-encoded username and password instead of a token via the Authorization
header in every request:
const credential = `${USERNAME}:${PASSWORD}`;
const token = Buffer.from(credential).toString('base64');
axios.get('/api/protected-resource', {
headers: {
Authorization: `Basic ${token}`
}
});
While this works, it requires you to manually encode the credentials.
Axios has built-in support for basic auth, so it automatically encodes the USERNAME
and PASSWORD
credentials. This way, all you have to do to invoke APIs protected with basic auth is add an auth
property to the config object with an object value containing the credentials:
axios.get('/api/protected-resource', {
auth: {
username: USERNAME,
password: PASSWORD
}
});
Monitoring request progress
Another interesting feature of Axios is the ability to monitor request progress. This is especially useful when downloading or uploading large files. The example provided in the Axios documentation gives you a good idea of how that can be done. But for the sake of simplicity and style, we are going to use the Axios Progress Bar module in this tutorial.
The first thing we need to do to use this module is to include the related style and script:
rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/rikmms/progress-bar-4-axios/0a3acf92/dist/nprogress.css" />
<span class="na">src="https://cdn.rawgit.com/rikmms/progress-bar-4-axios/0a3acf92/dist/index.js">
Then we can implement the progress bar like this:
loadProgressBar()
const url = 'https://media.giphy.com/media/C6JQPEUsZUyVq/giphy.gif';
function downloadFile(url) {
axios.get(url)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
downloadFile(url);
To change the default styling of the progress bar, we can override the following style rules:
#nprogress .bar {
background: red !important;
}
#nprogress .peg {
box-shadow: 0 0 10px red, 0 0 5px red !important;
}
#nprogress .spinner-icon {
border-top-color: red !important;
border-left-color: red !important;
}
Canceling requests with Axios
In some situations, you may no longer care about the result and want to cancel a request that’s already been sent. This can be done by using AbortController
. You can create an AbortController
instance and set its corresponding AbortSignal
instance as the value of the signal
property of the config object.
Here's a simple example:
const controller = new AbortController();
axios
.get("https://media.giphy.com/media/C6JQPEUsZUyVq/giphy.gif", {
signal: controller.signal,
})
.catch((error) => {
if (controller.signal.aborted) {
console.log(controller.signal.reason);
} else {
// handle error
}
});
// cancel the request (the reason parameter is optional)
controller.abort("Request canceled.");
Axios also has a built-in function for canceling requests. However, the built-in CancelToken
functionality is deprecated. You may still encounter it in a legacy codebase, but it is not advisable to use it in new projects.
Below is a basic example:
const source = axios.CancelToken.source();
axios.get('https://media.giphy.com/media/C6JQPEUsZUyVq/giphy.gif', {
cancelToken: source.token
}).catch(thrown => {
if (axios.isCancel(thrown)) {
console.log(thrown.message);
} else {
// handle error
}
});
// cancel the request (the message parameter is optional)
source.cancel('Request canceled.');
You can also create a cancel token by passing an executor function to the CancelToken
constructor, as shown below:
const CancelToken = axios.CancelToken;
let cancel;
axios.get('https://media.giphy.com/media/C6JQPEUsZUyVq/giphy.gif', {
// specify a cancel token
cancelToken: new CancelToken(c => {
// this function will receive a cancel function as a parameter
cancel = c;
})
}).catch(thrown => {
if (axios.isCancel(thrown)) {
console.log(thrown.message);
} else {
// handle error
}
});
// cancel the request
cancel('Request canceled.');
How to post a file from a form with Axios
We can use Axios with the FormData
object to streamline a file upload. To simplify the demonstration, I’m using React again to create a file upload component with basic error handling.
N.B., we are assuming that a backend API is available to support the file upload in this example. This will make more sense with a test backend API in your local development setup.
Let’s use React’s useState
Hook to manage the file selection and its upload status. Let’s also create a handler function (handleFileChange
) to manage the file selection, which basically updates the selectedFile
state to the file chosen by the user:
import { useState } from 'react';
import axios from 'axios';
const FileUploadBox = () => {
// State to manage the selected file and upload status
const [selectedFile, setSelectedFile] = useState(null);
const [uploadStatus, setUploadStatus] = useState('');
// Handle file selection
const handleFileChange = (event) => {
const file = event.target.files[0];
setSelectedFile(file);
};
}
We should now define a handler function (handleFileUpload
) for file upload, which creates a FormData
object if a file is selected. The selected file is then appended to this object, which will be sent in an Axios POST
request. Uploading a file is a heavy operation. Therefore, this handler function should execute asynchronously to allow other operations to continue without blocking the UI thread.
N.B., if your use case allows, you may also use an Axios PUT
request to upload a file, which takes a similar approach but may also require you to add some additional steps:
const FileUploadBox = () => {
// Previous code...
// Handle file upload
const handleFileUpload = async () => {
// Ensure a file is selected
if (!selectedFile) {
setUploadStatus('Please select a file first');
return;
}
// Create a FormData object to send the file
const formData = new FormData();
formData.append('file', selectedFile);
}
}
To the same function, i.e., handleFileUpload
, we can add a try...catch
block with a custom Axios instance pointing to our backend API’s endpoint, which is responsible for the file upload. Because it is a file upload, we must set the Content-Type
to multipart/form-data
to have our file properly parsed at the backend.
We may also reflect the upload progress in the frontend using the onUploadProgress
property of our custom Axios instance. If the request is successful, we set the uploadStatus
to something positive, which we can also show through a toast message later. Otherwise, we set a negative message to the uploadStatus
state:
const FileUploadBox = () => {
// Previous code...
// Handle file upload
const handleFileUpload = async () => {
try {
// Send POST request using Axios
const response = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
// Optional: track upload progress
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`Upload Progress: ${percentCompleted}%`);
}
});
// Handle successful upload
setUploadStatus('File uploaded successfully!');
console.log('Upload response:', response.data);
} catch (error) {
// Handle upload error
setUploadStatus('File upload failed');
console.error('Upload error:', error);
}
};
}
Finally, we should add some JSX to structure our file upload box and use the states, selection handlers, and file upload handlers appropriately, as shown below:
const FileUploadBox = () => {
// Previous code...
return (
<div className="upload-box-container">
<h2>File Upload</h2>
<input
type="file"
onChange={handleFileChange}
/>
<button
onClick={handleFileUpload}
disabled={!selectedFile}
>
Upload File
</button>
{uploadStatus && (
<p>
{uploadStatus}
</p>
)}
</div>
);
};
export default FileUploadComponent;
As an assignment, you may try adding previously discussed Axios interceptors-based error handling to this example. Find the code for this example in this StackBlitz demo.
Popular Axios libraries
Axios’ rise in popularity among developers has resulted in a rich selection of third-party libraries that extend its functionality. From testers to loggers, there’s a library for almost any additional feature you may need when using Axios. Here are some libraries that are currently available:
- axios-vcr — Records and replays requests in JavaScript
- axios-response-logger — Axios interceptor that logs responses
- axios-method-override — Axios request method override plugin
- axios-extensions — Axios extensions lib, including throttle and cache GET request features
- axios-api-versioning — Add easy-to-manage API versioning to Axios
- axios-cache-plugin — Helps you cache GET requests when using Axios
- axios-cookiejar-support — Adds tough-cookie support to Axios
- react-hooks-axios — Custom React Hooks for Axios
- moxios — Mock Axios requests for testing
- redux-saga-requests — Redux-Saga add-on to simplify handling AJAX requests
- axios-fetch — Web API Fetch implementation backed by an Axios client
- axios-curlirize — Logs any Axios request as a curl command in the console
- axios-actions — Bundles endpoints as callable, reusable services
- mocha-axios — HTTP assertions for Mocha using Axios
- axios-mock-adapter — Axios adapter that allows you to easily mock requests
- axios-debug-log — Axios interceptor of logging request and response with debug library
- redux-axios-middleware — Redux middleware for fetching data with Axios HTTP client
- axiosist — Axios-based supertest that converts the Node.js request handler to an Axios adapter; used for Node.js server unit test
Axios FAQs
What is Axios in JavaScript?
Axios is an open-source HTTP library for JavaScript that lets developers make HTTP requests from both the browser and Node.js.
How do I make a GET request with Axios?
To make a GET request with Axios, import the library, then call the axios.get(url)
with your API endpoint. Handle the response using .then()
for success or .catch()
for errors.
Why use Axios instead of Fetch?
Axios offers features like automatic JSON data transformation, interceptors, and better error handling, which makes it convenient for complex applications. For a detailed comparison of both tools, refer to our article, Axios vs. Fetch.
What are Axios interceptors used for?
Axios interceptors are functions that intercept and handle HTTP requests and responses. These functions act as middlewares that can be used to transform and modify requests before they are sent, or manipulate responses before you pass them to your functions.
Why does Axios set my content-type header to application/x-www-form-urlencoded
?
Axios automatically serializes objects to JSON and simultaneously sets the headers for you.
Wrapping up
There's a good reason Axios is so popular among developers; it's packed with useful features. In this post, we took a look at several key features of Axios and learned how to use them in practice. But there are still many aspects of Axios that we haven’t discussed. Be sure to check out the Axios GitHub page to learn more.
Do you have any tips on using Axios? Let us know in the comments!
LogRocket: Debug JavaScript errors more easily by understanding the context
Debugging code is always a tedious task. But the more you understand your errors, the easier it is to fix them.
LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to see exactly what the user did that led to an error.
LogRocket records console logs, page load times, stack traces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!