Что такое Fetch API в JavaScript?
Fetch API в JavaScript
Fetch API — современный браузерный интерфейс для выполнения HTTP-запросов. В отличие от старого XMLHttpRequest, Fetch работает на промисах, что делает код чище и удобнее для асинхронной обработки.
Базовый синтаксис
Функция fetch() принимает URL и необязательный объект настроек, возвращает промис, который разрешается объектом Response.
fetch('https://api.example.com/users')
.then(response => response.json()) // парсим тело ответа как JSON
.then(data => console.log(data))
.catch(error => console.error('Ошибка запроса:', error));
Объект Response
Response содержит метаданные ответа и методы для чтения тела:
response.ok—true, если статус в диапазоне 200–299response.status— числовой HTTP-статусresponse.json()— парсит тело как JSON, возвращает промисresponse.text()— возвращает тело как строкуresponse.blob()— возвращает бинарные данные
Важная особенность обработки ошибок
Fetch не отклоняет промис при HTTP-ошибках (4xx, 5xx). Промис отклоняется только при сетевом сбое. Поэтому статус нужно проверять вручную:
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
// fetch не выбросит ошибку сам — делаем это явно
throw new Error(`Ошибка HTTP: ${response.status}`);
}
const data = await response.json();
POST-запрос с телом
Для отправки данных передаём объект настроек:
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'Иван', age: 25 }), // сериализуем объект в строку
});
const newUser = await response.json();
Отмена запроса через AbortController
const controller = new AbortController();
// Отменяем запрос через 5 секунд
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('https://api.example.com/data', {
signal: controller.signal, // передаём сигнал отмены
});
const data = await response.json();
clearTimeout(timeoutId);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Запрос отменён по таймауту');
}
}
Fetch vs XMLHttpRequest
| Fetch | XMLHttpRequest | |
|---|---|---|
| Синтаксис | Промисы | Колбэки |
| Отмена | AbortController | xhr.abort() |
| Прогресс загрузки | Только через Streams API | onprogress |
| Поддержка | Все современные браузеры | Везде |
Поддержка браузерами
Fetch поддерживается всеми современными браузерами. Для старых окружений используется полифил (whatwg-fetch) или библиотека axios.
Что хочет услышать интервьюер
Понимание того, что Fetch возвращает промис и почему это лучше колбэков XHR
Знание двухшаговой работы с ответом: сначала получить Response, затем вызвать .json()/.text()
Осознание ловушки с ошибками: 404/500 не отклоняют промис — нужна проверка response.ok
Умение выполнить POST-запрос с JSON-телом и правильными заголовками
Знание об AbortController для отмены запросов
Пример: GET, POST и отмена запроса через AbortController
// GET-запрос с обработкой ошибок
async function getUser(id: number): Promise<User> {
const response = await fetch(`https://api.example.com/users/${id}`);
// fetch не выбрасывает при 4xx/5xx — проверяем сами
if (!response.ok) {
throw new Error(`Не удалось получить пользователя: ${response.status}`);
}
return response.json() as Promise<User>;
}
// POST-запрос — создание ресурса
async function createUser(userData: Omit<User, 'id'>): Promise<User> {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // обязательно при отправке JSON
},
body: JSON.stringify(userData),
});
if (!response.ok) {
throw new Error(`Ошибка создания: ${response.status}`);
}
return response.json() as Promise<User>;
}
// Запрос с таймаутом через AbortController
async function fetchWithTimeout(url: string, timeoutMs: number): Promise<Response> {
const controller = new AbortController();
const timerId = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, { signal: controller.signal });
return response;
} finally {
clearTimeout(timerId); // очищаем таймер при любом исходе
}
}
Типичные ошибки
Считать, что fetch автоматически выбрасывает ошибку при 4xx/5xx статусах — промис отклоняется только при сетевом сбое
Забывать вызвать .json() или .text() для чтения тела ответа и не понимать, что Response — это поток
Не передавать 'Content-Type': 'application/json' при отправке JSON в теле POST-запроса
Путать fetch в браузере и Node.js — в старых версиях Node fetch не встроен и требует пакет node-fetch
Не использовать AbortController для запросов с таймаутом или при размонтировании компонента


