Axios: инстансы и интерсепторы
↑ 5.4 Работа с API: REST, GraphQL, WebSocket · ← Предыдущая · → Следующая
Зачем это на собесе
Типовая задача: подстановка токена, обновление при 401, общий обработчик ошибок.
Объяснение
export const api = axios.create({ baseURL: import.meta.env.VITE_API_URL, timeout: 15_000, headers: { Accept: "application/json" }, withCredentials: false });
api.interceptors.request.use((cfg) => {
const token = useAuthStore().accessToken;
if (token) cfg.headers.Authorization = `Bearer ${token}`;
cfg.headers["X-Request-Id"] = crypto.randomUUID(); // корреляция с логами бэкенда
return cfg;
});
// Обновление токена при 401 с очередью запросов и защитой от гонок
let refreshing: Promise<string> | null = null;
api.interceptors.response.use(
(res) => res,
async (error: AxiosError) => {
const original = error.config as AxiosRequestConfig & { _retry?: boolean };
if (error.response?.status === 401 && !original._retry && !original.url?.includes("/auth/")) {
original._retry = true;
refreshing ??= useAuthStore().refresh().finally(() => (refreshing = null)); // один refresh на все запросы
try { const t = await refreshing; original.headers = { ...original.headers, Authorization: `Bearer ${t}` }; return api(original); }
catch { useAuthStore().logout(); }
}
return Promise.reject(normalizeError(error)); // единый формат ошибок
},
);Что типично делают интерсепторы:
| Задача | Интерсептор |
|---|---|
Токен, язык (Accept-Language), tenant | request |
Корреляционный id, трассировка (traceparent) | request |
| Обновление токена, редирект на логин | response (401) |
| Нормализация ошибок, показ уведомлений | response |
| Логирование, метрики | оба |
| Повторы | response (с ограничением) |
| Лоадер | счётчик активных запросов |
Несколько инстансов: публичный API, внутренний, внешние сервисы — с разными baseURL/авторизацией. Типизация: api.get<Order[]>("/orders"), обобщения обёртки.
Перевод на fetch-адаптер или ky/ofetch возможен; логика интерсепторов сохраняется (обёртка с хуками).
Нюансы и подводные камни
- Бесконечный цикл при повторе запроса с 401: флаг
_retry, исключение auth-эндпоинтов. - Параллельные 401 вызывают несколько
refresh: объединяйте в один промис. - Интерсептор не должен показывать уведомление на каждую ошибку (ожидаемые 4xx обрабатываются локально).
- Утечки при добавлении интерсепторов в
setupбезeject. - Секреты в логах интерсептора.
Практика
- Реализуйте обновление токена с очередью запросов.
- Настройте единый формат ошибок и связь с Vue Query.
- Добавьте
X-Request-Id/traceparentв исходящие запросы.
Вопросы с ответами
Как реализовать refresh токена в Axios?
Response-интерсептор на 401: один общий запрос обновления, повтор оригинального запроса с новым токеном и флагом
_retry.
Зачем несколько инстансов?
Разные базовые URL, заголовки и политики для разных сервисов.