Editor’s note: This article was last updated on 9 October 2023 to update code snippets based on the newest Axios version and include information about global headers, conditional headers, and solutions for common HTTP headers-related issues.
Nearly everything that is visible in a user’s browser is transmitted over HTTP using the request-response pattern. These HTTP-based network requests play an important role in modern internet communications. A key component of an HTTP request is the header that is included before the body of the message. HTTP request headers are used to provide additional information about the request, such as details about the requested information, the sender, and how the sender wishes to connect with the recipient.
Web server implementations and browsers typically use standard HTTP headers internally to maintain connections. Web developers also use standard headers and implement custom headers in their web apps, so working with HTTP headers is a skill that every web developer should have.
Axios is a flexible and robust solution for making HTTP requests and intercepting HTTP responses from both Node.js applications and the browser. In this article, we’ll explore different ways that Axios can be used to set request headers for API calls.
You can install Axios with popular Node package managers:
// via npm npm install axios // via yarn yarn add axios // via bower bower install axios // via pnpm pnpm add axios
It’s also possible to load Axios directly to the browser via jsDelivr and unpkg CDNs:
// via jsdelivr <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> // via unpkg <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Once you install Axios, you can import it into your app as follows:
import axios from 'axios';
Due to the stateless behavior of the HTTP protocol, headers are typically sent for each HTTP message. So, Axios offers you a way to set headers per request when you make a new request using its API.
For example, if you send a new GET
request to the /users
endpoint, you can set a custom header only for that particular request. If you send another GET
request to /users/101
, Axios won’t automatically add the custom header that you sent for the /users
endpoint. We can refer to these as per-request headers because they are added only for one particular request.
Axios global headers are sent for multiple requests even though you don’t explicitly mention them in each request. For example, you can configure Axios to set up a custom global header for all GET
endpoints. Attaching the Authorization
header to all outgoing requests is a popular usage of global headers.
We can use Axios request configuration to set per-request headers, and Axios global configuration, instances, and interceptors to set global headers, as explained in the following sections.
Axios methods such as post()
, get()
, put()
, etc., enable us to attach headers to a specific request by attaching a headers
object in the Axios request configuration. For example, you can set custom headers for a single GET
request using the following approach:
axios.get('/users', { headers: { 'MyCustomHeader1': '1', 'MyCustomHeader2': '2' } }) .then((res) => console.log(res.data)) .catch((err) => console.error(err));
In the above example, we passed the API endpoint string to the first parameter and the Axios configuration object to the second parameter.
With POST
requests, we need to pass data using the second parameter, so we should send the headers
object from the third configuration parameter, as shown here:
const data = { customerId: 100, items: [] }; axios.post('/invoices', data, { headers: { 'MyCustomHeader1': '1', 'MyCustomHeader2': '2' } }) .then((res) => console.log(res.data)) .catch((err) => console.error(err));
In the above example, we passed the API endpoint string with the first parameter, the data
object via the second parameter, and the Axios configuration object with custom headers via the third parameter.
Sometimes, headers may need to be set automatically for multiple or subsequent requests. For example, you may need to send a specific configuration property from all React Native mobile API clients via a custom header. Adding this custom header to all places where you call Axios functions may add repetitive code segments to your codebase.
We can address this by setting global headers and updating the default configuration. This code sets a global authorization header for all requests:
axios.defaults.headers.common['Authorization'] = `Bearer ${localStorage.getItem('access_token')}`;
This code sets authorization headers for all POST
requests:
axios.defaults.headers.post['Authorization'] = `Bearer ${localStorage.getItem('access_token')}`;
Similarly, it’s also possible to set global headers for other HTTP methods.
We typically work with web apps that have one RESTful API URL, but some large-scale apps can connect with multiple RESTful URLs. If we set headers in the Axios default global configuration, all RESTful backends will receive those headers. To prevent this situation, Axios offers a way to create several Axios instances with isolated global configurations. We can also set request headers for API calls by creating a specific instance of Axios.
To correctly set up headers for each request, we can create an instance of Axios using [axios.create](https://blog.logrocket.com/understanding-axios-create/)
and then set a custom configuration on that instance, as shown here:
const instance = axios.create({ baseURL: 'http://localhost:3000', headers: { 'MyCustomHeader1': '1', 'MyCustomHeader2': '2' } });
We can reuse this configuration each time we send a new request using this particular Axios instance.
When we use the instance
object to make a request, the authorization header will be attached automatically:
instance.get('/users') .then((res) => console.log(res.data)) .catch((err) => console.error(err));
As you normally expect, if you create a new Axios instance for another RESTful API, it won’t inherit these global headers from the previous instance because those are two separate instances.
We can also use Axios interceptors — functions that are called by Axios — to set request headers for API calls. Interceptors may be used to alter a request before it is transmitted or to modify a response before it is delivered to callbacks. They are essentially equivalent to middleware from Express or Mongoose.
I previously worked on a project that required an authorization header, containing the user access token, to be appended to every request. It was a financial application, and the system needed to verify user identity for every request. This is an example in which it would have been preferable to automatically attach the authorization header to every request, rather than setting them individually.
Authentication is one of the most common applications for interceptors. A client app often verifies user identity to the server by submitting a secret access token in the authorization header.
We can use Axios interceptors to automatically set the Authorization
header for all requests:
axios.interceptors.request.use( config => { config.headers['Authorization'] = `Bearer ${localStorage.getItem('access_token')}`; return config; }, error => { return Promise.reject(error); } );
In this example, we used the axios.interceptors.request.use
method to update each request header and set the access token in the Authorization
HTTP header.
We target the Authorization
header from the config.headers
object and set a Bearer
token, which is stored in localStorage
, as its value.
In previous code examples, I showed you several approaches to set headers without conditional statements — those headers contain some fixed, hardcoded values and an access token from localStorage
.
In some scenarios, we have to conditionally change headers based on environment variables, request details, and other configuration or application runtime values. Axios is flexible and lets you change global headers at any time:
axios.defaults.headers.common['MyGlobalHeader'] = `1`; setTimeout(() => { axios.defaults.headers.common['MyGlobalHeader'] = `2`; }, 5000);
So, we can conditionally change global headers based on various factors. For example, the following code segment conditionally adds some internal debugging headers based on an environment variable:
function setHeaders(options = {}) { if(process.env.DEBUG_MODE) { axios.defaults.headers.common['Debug-Mode'] = `1`; axios.defaults.headers.common['Debug-Extras'] = getDebugExtras(); } }
Similarly, you can use the instance.defaults.headers
property to conditionally change the headers of an Axios instance.
If you need to set conditional headers based on incoming requests, you can use a request interceptor as follows:
axios.interceptors.request.use( config => { if(config.url.includes('/users')) { config.headers['MyCustomHeader1'] = 1; } return config; } );
The above sample interceptor sets a custom header only for user endpoint requests by comparing the request URL. Similarly, you can set conditional headers based on other request details, such as the HTTP method, JSON payload, etc.
Axios response interceptors are useful for monitoring access tokens for impending token renewal. A refreshToken()
function can be used to update a token before it expires:
const refreshToken = async () => { // gets new token }
We can also call the axios.interceptors.response.use()
method to get a new access token whenever a response returns a 40``1
error, meaning the existing token has expired:
axios.interceptors.response.use( response => { return response; }, async error => { if(error.response.status == 401) { let token = await refreshToken(); axios.defaults.headers.common['Authorization'] = 'Bearer ' + token; } } );
In this example, the axios.interceptors.response.use
method intercepts all incoming responses and then checks the status of response
. If the request that triggered response
is not authenticated, then the token is expired. In that case, we conditionally call for the refreshToken()
function to obtain a new access token and use it with new outgoing requests by updating the global authorization header. This flow is now pre-developed in the axios-auth-refresh interceptor library.
Here are solutions for some common HTTP headers-related issues that you may face while using Axios:
According to RFCs, every HTTP header should be meaningful, readable, and case-insensitive. Developers may try to access headers directly with uppercase and lowercase mixed keys and might write the wrong header names.
Look at the following examples:
console.log(res.headers['Content-Length']); // undefined console.log(res.headers['content_length']); // undefined
To fix this issue, make sure to access headers with valid lowercase keys:
console.log(res.headers['content-length']); // 100
As a general practice, developers typically use title case header names, i.e., Authorization
, Content-Type
, etc. But make sure to use lowercase names to access them in Axios.
CORS (Cross-Origin Resource Sharing) is an HTTP header-based security mechanism to let web app frontends use resources from different domains securely. The browser won’t let apps access backend resources if required CORS headers are not present in the backend HTTP responses.
This error is common with Axios, too. I got the following errors when I tried to connect to my local Node.js test server from a CodeSandbox React app:
To fix this, if you own the server or you can configure it, you can add CORS headers to server responses. For example, the following Express.js setup accepts any HTTP method from any domain:
import express from 'express'; import cors from 'cors'; const app = express(); const port = 3000; app.use(cors());
If you have no control over the server, you can implement a proxy server with cors-anywhere. Learn more in this ultimate guide to CORS.
Content-Type
headerAxios automatically sets the Content-Type
header based on the payload format. For example, the following POST
request’s content type becomes application/json
:
const data = { customerId: 100, items: [] }; axios.post('/invoices', data) .then((res) => console.log(res.data)) .catch((err) => console.error(err));
If the above data
object is null
or undefined
, Axios can’t determine the payload type as JSON, so we can fix it by sending an empty JavaScript object as follows:
axios.post('/invoices', {}) .then((res) => console.log(res.data)) .catch((err) => console.error(err));
Alternatively, you also can set the Content-Type
header explicitly. If you are stuck with a unique headers-related error apart from these, you can find answers by opening a new discussion thread on the Axios GitHub repository.
In this article, we examined how to set HTTP request headers with Axios by passing the headers
object, updating the default global configuration, creating a specific Axios instance, and using Axios interceptors. We also discussed how to conditionally set headers, and found solutions for common HTTP headers-related issues that many web developers face with Axios.
For information about additional features of the Axios HTTP client, check out “How to make HTTP requests with Axios.” Additionally, see Axios’ official documentation and GitHub repository.
There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.
LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.
LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.
Build confidently — start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowToast notifications are messages that appear on the screen to provide feedback to users. When users interact with the user […]
Deno’s features and built-in TypeScript support make it appealing for developers seeking a secure and streamlined development experience.
It can be difficult to choose between types and interfaces in TypeScript, but in this post, you’ll learn which to use in specific use cases.
This tutorial demonstrates how to build, integrate, and customize a bottom navigation bar in a Flutter app.
3 Replies to "Using Axios to set request headers"
You have syntax errors in your examples – misplaced } with ` within template strings in both examples: axios.create and axios.interceptors.request.use
Thanks for pointing that out. We’ve updated the code accordingly.
I am facing Invalid Host Header..
My vue.config.ts
// vue.config.ts
import { defineConfig } from ‘vite’;
export default defineConfig({
// Set the entry point for your application (main.ts)
build: {
rollupOptions: {
input: ‘./src/main.ts’,
},
},
server: {
port: 8080,
allowedHosts: [
‘courserev-dev-super-admin-dashboard-development-v-g4pfhuoefa-ue.a.run.app’,
],
proxy: {
// Add any proxy configurations if needed
},
},
});