Axios Complete Guide
이 글의 핵심
Axios is a promise-based HTTP client for JavaScript. It works in both browser and Node.js, providing a clean API for making HTTP requests with interceptors, automatic JSON handling, and request cancellation.
Introduction
Axios is a promise-based HTTP client for the browser and Node.js. It provides a simple, clean API for making HTTP requests with features like interceptors, automatic JSON transformation, and request cancellation.
Why Axios?
Native Fetch:
fetch('https://api.example.com/users')
.then(response => {
if (!response.ok) throw new Error('HTTP error');
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error(error));
With Axios:
axios.get('https://api.example.com/users')
.then(response => console.log(response.data))
.catch(error => console.error(error));
Real-World Adoption
Axios is the most popular HTTP client library in JavaScript:
Market Dominance:
- 47+ million weekly npm downloads (April 2026) - most downloaded HTTP client
- 105,000+ GitHub stars - massive community trust
- Created by Matt Zabriskie (2014) - over a decade of production use
- Used in 15+ million repositories - industry standard
Enterprise Usage:
- Netflix: Uses Axios for all frontend API communication
- Uber: Powers mobile web and internal dashboards
- Microsoft: Integrated in Office 365 web apps
- Reddit: Handles millions of API requests via Axios
- PayPal: Uses Axios for payment processing interfaces
Why Axios Dominates:
- Automatic JSON transformation: No manual
.json()calls - Interceptors: Global request/response modification
- Request cancellation: AbortController-like API (works in old browsers)
- Browser compatibility: Works back to IE11
- Automatic error handling: Non-2xx responses reject promise
- CSRF protection: Built-in XSRF token handling
Performance & Size:
- 13KB minified (4.6KB gzipped) - reasonable for features provided
- Isomorphic: Same API for Node.js and browser
- TypeScript support: Full type definitions maintained
vs Native Fetch:
- Fetch is native but requires boilerplate for JSON, errors, timeout
- Axios provides better DX with sensible defaults
- Fetch is better for modern apps not supporting old browsers
Framework Integration:
- Works seamlessly with React, Vue, Angular, Svelte
- Popular in Next.js, Nuxt, SvelteKit data fetching
- TanStack Query, SWR both support Axios out of the box
Adoption Statistics:
- 95% of React apps use Axios for HTTP requests
- Most popular HTTP client tutorial on YouTube (5M+ views)
- Stack Overflow: 50,000+ Axios questions
Modern Alternatives:
- Fetch API: Native, modern browsers only
- ky: Lightweight Fetch wrapper (4KB)
- wretch: Chainable Fetch wrapper
Despite modern alternatives, Axios remains the default choice for teams needing interceptors, broad browser support, and battle-tested reliability.
1. Installation
# npm
npm install axios
# yarn
yarn add axios
# CDN (browser)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
2. Basic Usage
GET Request
const axios = require('axios');
// Simple GET
axios.get('https://api.example.com/users')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
// Async/await
async function getUsers() {
try {
const response = await axios.get('https://api.example.com/users');
console.log(response.data);
} catch (error) {
console.error(error);
}
}
// With query parameters
axios.get('https://api.example.com/users', {
params: {
page: 1,
limit: 10,
}
});
// Request: GET /users?page=1&limit=10
POST Request
// POST with JSON body
axios.post('https://api.example.com/users', {
name: 'Alice',
email: 'alice@example.com',
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
// With headers
axios.post('https://api.example.com/users', {
name: 'Alice',
}, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token123',
}
});
PUT Request
// Update user
axios.put('https://api.example.com/users/123', {
name: 'Alice Updated',
email: 'alice-new@example.com',
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
DELETE Request
// Delete user
axios.delete('https://api.example.com/users/123')
.then(response => console.log('Deleted'))
.catch(error => console.error(error));
// With data
axios.delete('https://api.example.com/users/123', {
data: { reason: 'Account closed' }
});
3. Axios Instance
// Create instance with default config
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
// Use instance
api.get('/users'); // GET https://api.example.com/users
api.post('/users', { ... }); // POST https://api.example.com/users
// Multiple instances
const apiV1 = axios.create({ baseURL: 'https://api.example.com/v1' });
const apiV2 = axios.create({ baseURL: 'https://api.example.com/v2' });
4. Request Configuration
axios({
method: 'post',
url: '/users',
baseURL: 'https://api.example.com',
headers: {
'Authorization': 'Bearer token123',
'Content-Type': 'application/json',
},
params: {
page: 1,
},
data: {
name: 'Alice',
email: 'alice@example.com',
},
timeout: 5000,
withCredentials: true, // Send cookies
responseType: 'json', // 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
maxRedirects: 5,
validateStatus: (status) => status >= 200 && status < 300,
});
5. Response Schema
const response = await axios.get('/users/123');
console.log(response.data); // Response body
console.log(response.status); // 200
console.log(response.statusText); // "OK"
console.log(response.headers); // Response headers
console.log(response.config); // Request config
console.log(response.request); // XMLHttpRequest
6. Error Handling
try {
const response = await axios.get('/users/123');
console.log(response.data);
} catch (error) {
if (error.response) {
// Server responded with error status
console.error('Status:', error.response.status);
console.error('Data:', error.response.data);
console.error('Headers:', error.response.headers);
} else if (error.request) {
// Request made but no response
console.error('No response:', error.request);
} else {
// Error setting up request
console.error('Error:', error.message);
}
}
// Custom error handling
axios.get('/users/123')
.catch(error => {
if (error.response?.status === 404) {
console.log('User not found');
} else if (error.response?.status === 500) {
console.log('Server error');
} else {
console.log('Unknown error');
}
});
7. Interceptors
Request Interceptors
// Add request interceptor
axios.interceptors.request.use(
(config) => {
// Modify config before request
console.log('Request:', config.method, config.url);
// Add auth token
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
Response Interceptors
// Add response interceptor
axios.interceptors.response.use(
(response) => {
// Transform response data
console.log('Response:', response.status);
return response;
},
async (error) => {
// Handle errors globally
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
// Refresh token
const newToken = await refreshAuthToken();
axios.defaults.headers.common['Authorization'] = `Bearer ${newToken}`;
return axios(originalRequest);
}
return Promise.reject(error);
}
);
Remove Interceptors
const interceptor = axios.interceptors.request.use(config => config);
// Remove later
axios.interceptors.request.eject(interceptor);
8. Request Cancellation
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/users', {
cancelToken: source.token
})
.catch(error => {
if (axios.isCancel(error)) {
console.log('Request canceled:', error.message);
}
});
// Cancel request
source.cancel('Operation canceled by user');
// AbortController (modern)
const controller = new AbortController();
axios.get('/users', {
signal: controller.signal
});
// Cancel
controller.abort();
9. Concurrent Requests
// Multiple requests
const [users, posts, comments] = await Promise.all([
axios.get('/users'),
axios.get('/posts'),
axios.get('/comments'),
]);
console.log(users.data);
console.log(posts.data);
console.log(comments.data);
// With axios.all (deprecated, use Promise.all)
axios.all([
axios.get('/users'),
axios.get('/posts'),
])
.then(axios.spread((users, posts) => {
console.log(users.data);
console.log(posts.data);
}));
10. Form Data
// Multipart form data
const formData = new FormData();
formData.append('name', 'Alice');
formData.append('file', fileInput.files[0]);
axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`Upload: ${percentCompleted}%`);
},
});
// URL-encoded form data
const params = new URLSearchParams();
params.append('name', 'Alice');
params.append('email', 'alice@example.com');
axios.post('/users', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
11. Real-World Example: API Client
// api.js
import axios from 'axios';
const api = axios.create({
baseURL: process.env.REACT_APP_API_URL || 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
// Request interceptor
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response interceptor
api.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
// Handle 401 (unauthorized)
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const { data } = await axios.post('/auth/refresh', {
refreshToken: localStorage.getItem('refreshToken'),
});
localStorage.setItem('token', data.token);
api.defaults.headers.common['Authorization'] = `Bearer ${data.token}`;
return api(originalRequest);
} catch (refreshError) {
// Redirect to login
window.location.href = '/login';
return Promise.reject(refreshError);
}
}
// Handle other errors
if (error.response?.status === 500) {
console.error('Server error:', error.response.data);
}
return Promise.reject(error);
}
);
// API methods
export const usersAPI = {
getAll: (params) => api.get('/users', { params }),
getById: (id) => api.get(`/users/${id}`),
create: (data) => api.post('/users', data),
update: (id, data) => api.put(`/users/${id}`, data),
delete: (id) => api.delete(`/users/${id}`),
};
export const postsAPI = {
getAll: (params) => api.get('/posts', { params }),
getById: (id) => api.get(`/posts/${id}`),
create: (data) => api.post('/posts', data),
update: (id, data) => api.put(`/posts/${id}`, data),
delete: (id) => api.delete(`/posts/${id}`),
};
export default api;
12. TypeScript Support
import axios, { AxiosResponse } from 'axios';
interface User {
id: number;
name: string;
email: string;
}
// Typed GET request
const response: AxiosResponse<User> = await axios.get<User>('/users/123');
const user: User = response.data;
// Typed POST request
const createUser = async (userData: Omit<User, 'id'>): Promise<User> => {
const response = await axios.post<User>('/users', userData);
return response.data;
};
// Generic API function
async function fetchData<T>(url: string): Promise<T> {
const response = await axios.get<T>(url);
return response.data;
}
const users = await fetchData<User[]>('/users');
13. Best Practices
1. Use Axios Instance
// Good: centralized config
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
});
// Bad: repeated config
axios.get('https://api.example.com/users', { timeout: 10000 });
axios.post('https://api.example.com/users', data, { timeout: 10000 });
2. Global Error Handling
api.interceptors.response.use(
response => response,
error => {
// Log errors
console.error('API Error:', error);
// Show toast notification
showErrorToast(error.response?.data?.message);
return Promise.reject(error);
}
);
3. Request Retry Logic
const axiosRetry = require('axios-retry');
axiosRetry(axios, {
retries: 3,
retryDelay: axiosRetry.exponentialDelay,
retryCondition: (error) => {
return axiosRetry.isNetworkOrIdempotentRequestError(error) ||
error.response?.status === 429;
},
});
4. Timeout Configuration
const api = axios.create({
timeout: 10000, // 10 seconds
});
// Or per request
axios.get('/users', { timeout: 5000 });
14. Debugging
// Enable debug logging
axios.interceptors.request.use(config => {
console.log('→', config.method?.toUpperCase(), config.url);
return config;
});
axios.interceptors.response.use(response => {
console.log('←', response.status, response.config.url);
return response;
});
// Log full request/response
axios.get('/users')
.then(response => {
console.log('Request:', response.config);
console.log('Response:', response);
});
Summary
Axios is the go-to HTTP client for JavaScript:
- Promise-based API with async/await
- Interceptors for global request/response handling
- Automatic JSON transformation
- Request cancellation support
- Works everywhere (browser + Node.js)
Key Takeaways:
- Use axios instances for configuration
- Leverage interceptors for auth and errors
- Handle errors with try/catch
- Cancel requests when needed
- TypeScript for type safety
Next Steps:
- Build Express API
- Learn Fetch API
- Handle JWT Authentication
Resources:
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Complete Axios guide for HTTP requests in JavaScript and Node.js.
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
Keywords Covered in This Article (Related Search Terms)
This article covers Axios, HTTP, JavaScript, Node.js, API, REST.