Что Axios всё ещё даёт вам по сравнению с Fetch
Fetch API значительно повзрослел. Он встроен в каждый современный браузер, доступен нативно в Node.js начиная с v18 благодаря Undici, и способен обрабатывать JSON, отмену запросов и стриминг. Для многих фронтенд-запросов к API его действительно достаточно.
Так почему же команды всё ещё обращаются к Axios? Не из привычки, а потому что Axios по-прежнему решает конкретные проблемы developer experience, которые Fetch оставляет вам. Вот где этот разрыв реально проявляется.
Ключевые выводы
- Fetch успешно резолвится при ответах 4xx и 5xx, заставляя вручную проверять
response.okдля каждого запроса. - Перехватчики (interceptors) Axios централизуют сквозную функциональность, такую как токены аутентификации, логирование и нормализация ошибок, без шаблонного кода в каждом запросе.
- Общая конфигурация через
axios.create()упрощает работу с несколькими API, требующими разных базовых URL, заголовков или таймаутов. - Отслеживание прогресса загрузки и встроенные опции таймаута остаются эксклюзивными возможностями Axios, которые Fetch не может предложить нативно.
- Для небольших проектов с минимальными HTTP-потребностями Fetch — правильный выбор по умолчанию без зависимостей.
Axios против Fetch: где реальные различия
1. Обработка HTTP-ошибок, работающая по умолчанию
Fetch отклоняет промис только при сетевых сбоях. Ответы 404 или 500 резолвятся успешно — вам приходится каждый раз самостоятельно проверять response.ok.
// Fetch — нужно проверять вручную
const res = await fetch('/api/user');
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);
const data = await res.json();
// Axios — автоматически отклоняет при 4xx/5xx по умолчанию
const { data } = await axios.get('/api/user');
В крупных приложениях с десятками эндпоинтов эта ручная проверка превращается в повторяющийся шаблонный код. Axios устраняет большую её часть по умолчанию.
2. Встроенные перехватчики запросов и ответов
Это та функция, которую разработчики чаще всего называют, выбирая Axios. Перехватчики позволяют один раз глобально привязать логику — токены аутентификации, логирование, нормализацию ошибок — не затрагивая отдельные запросы.
axios.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${getToken()}`;
return config;
});
axios.interceptors.response.use(
response => response,
error => {
if (error.response?.status === 401) redirectToLogin();
return Promise.reject(error);
}
);
С Fetch это можно симулировать, обернув fetch() в собственную функцию. Но такая обёртка не является композируемой, не поддерживает стекирование, и поддерживать её приходится самому.
3. Общая конфигурация через инстансы Axios
Axios позволяет создавать изолированные инстансы с предустановленными базовыми URL, заголовками и таймаутами — паттерн, который действительно полезен, когда ваше приложение работает с несколькими API.
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 8000,
headers: { 'X-App-Version': '2.1.0' },
});
Чисто воспроизвести это с Fetch требует класса-обёртки или фабричной функции. Выполнимо, но это дополнительный объём работы, который вы берёте на себя.
Discover how at OpenReplay.com.
4. Отслеживание прогресса загрузки
В Fetch до сих пор нет стандартизированного нативного API для отслеживания прогресса загрузки в браузерах. Axios предоставляет onUploadProgress напрямую, опираясь под капотом на XMLHttpRequest в браузерах.
await axios.post('/upload', formData, {
onUploadProgress: e => {
if (e.total) {
console.log(`${Math.round((e.loaded / e.total) * 100)}%`);
}
},
});
Если вам нужен прогресс загрузки в среде, использующей только Fetch, придётся вернуться к голому XMLHttpRequest. Это реальный регресс.
5. Конфигурация таймаута без шаблонного кода с AbortController
Axios принимает опцию timeout напрямую. Fetch требует вручную подключать AbortController и setTimeout — это работает, но добавляет шума.
// Axios
await axios.get('/api/data', { timeout: 5000 });
// Эквивалент на Fetch
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), 5000);
try {
const res = await fetch('/api/data', { signal: controller.signal });
} finally {
clearTimeout(id);
}
Современные среды также поддерживают AbortSignal.timeout(), что значительно сокращает этот код, а поддержка в браузерах теперь широко доступна.
Краткое сравнение: возможности Axios против Fetch API
| Возможность | Fetch | Axios |
|---|---|---|
| Отклонение при HTTP-ошибках | Ручная проверка response.ok | Автоматически по умолчанию |
| Перехватчики | Требуется собственная обёртка | Встроенные |
| Общие инстансы | Ручной фабричный паттерн | axios.create() |
| Прогресс загрузки | Не поддерживается нативно | onUploadProgress |
| Таймаут запроса | AbortController + setTimeout | Опция timeout |
| Размер бандла | 0 КБ (нативный) | ~15 КБ в gzip |
Заключение
Fetch не является неполноценным. Для простых JavaScript HTTP-клиентов — пара эндпоинтов, без общей логики аутентификации, без прогресса загрузки — это правильный выбор по умолчанию. Никаких зависимостей, никаких накладных расходов.
Но Axios оправдывает своё место, когда сложность ваших фронтенд-запросов к API растёт. Перехватчики, общие инстансы, автоматическая обработка ошибок и прогресс загрузки — это функции, которые вы не будете замечать, пока они вам не понадобятся, а тогда вы захотите, чтобы они были встроенными, а не написанными вручную. Именно это Axios всё ещё даёт вам.
Часто задаваемые вопросы
Это зависит от сложности проекта. Для небольшого количества простых запросов Fetch достаточно и позволяет избежать зависимости. Для приложений с общей аутентификацией, централизованной обработкой ошибок, несколькими API-клиентами или требованиями к отслеживанию прогресса загрузки Axios экономит значительный объём шаблонного кода, который иначе пришлось бы реализовывать самостоятельно.
Частично. Можно обернуть fetch в функцию, которая внедряет заголовки или обрабатывает ошибки, но вы потеряете стекируемую и композируемую природу перехватчиков Axios. Каждая новая задача требует прямой модификации обёртки, а связывание нескольких независимых перехватчиков становится неудобным. Большинство команд, пытающихся это сделать, в итоге пересоздают уменьшенную и менее протестированную версию Axios.
Не совсем. Axios поддерживает прогресс загрузки и скачивания в Node.js, но реализация отличается от браузерной, поскольку Node не использует XMLHttpRequest. События прогресса в браузерах обычно более плавные и гранулярные, тогда как некоторые сценарии загрузки в Node.js — особенно загрузка FormData — имеют ограничения в зависимости от адаптера и среды выполнения.
Обе — достойные варианты. Ky — это небольшая обёртка на основе Fetch, добавляющая повторные попытки, хуки и таймауты, оставаясь при этом легковесной. Got богат функциями, но работает только в Node. Axios остаётся популярным, потому что работает и в браузере, и в Node с единым API, имеет широкую поддержку экосистемы и знаком большинству JavaScript-разработчиков.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.