Back

Что Axios всё ещё даёт вам по сравнению с Fetch

Что 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 требует класса-обёртки или фабричной функции. Выполнимо, но это дополнительный объём работы, который вы берёте на себя.


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

ВозможностьFetchAxios
Отклонение при 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.

OpenReplay