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: '[email protected]',
})
.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: '[email protected]',
})
.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: '[email protected]',
},
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', '[email protected]');
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](/en/blog/express-complete-guide/
- Learn [Fetch API](/en/blog/axios-complete-guide/
- Handle [JWT Authentication](/en/blog/jwt-authentication-guide/
Resources:
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. Complete Axios guide for HTTP requests in JavaScript and Node.js. Learn GET/POST/PUT/DELETE, interceptors, error handlin… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- [Express.js Complete Guide | Fast Node.js Web Framework](/en/blog/express-complete-guide/
이 글에서 다루는 키워드 (관련 검색어)
Axios, HTTP, JavaScript, Node.js, API, REST 등으로 검색하시면 이 글이 도움이 됩니다.