Fetch API предоставляет современный способ выполнения HTTP-запросов в
JavaScript, заменяя устаревший XMLHttpRequest. Основной
вызов функции fetch возвращает объект Promise,
который позволяет работать с асинхронными операциями через цепочки
.then() или с использованием async/await.
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Ошибка запроса:', error));
Ключевые моменты:
fetch по умолчанию выполняет GET-запрос.Response предоставляет методы
.json(), .text(), .blob() для
обработки ответа..catch(), но HTTP-статусы 4xx и 5xx не считаются ошибкой,
их нужно проверять вручную.fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error(`Ошибка HTTP: ${response.status}`);
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error(error));
Использование async/await делает код более читаемым и
последовательным. Асинхронная функция позволяет писать асинхронный код
почти так же, как синхронный:
async function getData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(`Ошибка HTTP: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
getData();
Особенности:
await приостанавливает выполнение функции до получения
результата Promise.try/catch упрощает контроль над
исключениями.Promise.all() для повышения производительности.async function getMultipleData() {
try {
const [users, posts] = await Promise.all([
fetch('https://api.example.com/users').then(res => res.json()),
fetch('https://api.example.com/posts').then(res => res.json())
]);
console.log(users, posts);
} catch (error) {
console.error(error);
}
}
fetch позволяет детально настраивать запрос через объект
настроек:
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer TOKEN'
},
body: JSON.stringify({ name: 'John', age: 30 }),
mode: 'cors',
cache: 'no-cache'
});
Основные опции:
method — HTTP-метод (GET, POST, PUT, DELETE).headers — объект заголовков, включая
Content-Type и авторизационные токены.body — данные запроса для POST/PUT. Для JSON нужно
использовать JSON.stringify().mode — режим CORS (cors,
no-cors, same-origin).credentials — контроль куки и авторизации
(omit, same-origin,
include).Cross-Origin Resource Sharing (CORS) ограничивает доступ к ресурсам
другого домена. Сервер должен отправлять заголовок
Access-Control-Allow-Origin, иначе браузер заблокирует
ответ.
fetch('https://api.otherdomain.com/data', { mode: 'cors' })
.then(res => res.json())
.catch(err => console.error('Ошибка CORS или сети', err));
Особенности:
no-cors позволяет отправлять запрос, но ограничивает
доступ к телу ответа.credentials: 'include' позволяет отправлять куки
при междоменных запросах.Fetch не поддерживает таймаут напрямую. Таймаут можно реализовать
через AbortController:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
fetch('https://api.example.com/data', { signal: controller.signal })
.then(res => res.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.error('Запрос прерван из-за таймаута');
} else {
console.error('Ошибка запроса', err);
}
})
.finally(() => clearTimeout(timeoutId));
Ключевые моменты:
AbortController позволяет прервать запрос вручную.Fetch поддерживает работу с потоками через
ReadableStream. Это позволяет обрабатывать большие данные
без полной загрузки в память:
fetch('https://api.example.com/large-file')
.then(response => {
const reader = response.body.getReader();
return new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
controller.enqueue(value);
push();
});
}
push();
}
});
})
.then(stream => new Response(stream))
.then(res => res.text())
.then(text => console.log(text));
Особенности:
TextDecoder позволяет декодировать
бинарные данные в текст по мере поступления.Наиболее распространённый сценарий — работа с JSON API. Часто
используется сочетание async/await и проверок статуса:
async function fetchJson(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Ошибка HTTP: ${response.status}`);
}
return response.json();
}
(async () => {
try {
const data = await fetchJson('https://api.example.com/data');
console.log(data);
} catch (err) {
console.error(err);
}
})();
Практические рекомендации:
response.ok для надёжной обработки
ошибок.Для повышения эффективности можно выполнять несколько запросов
параллельно с помощью Promise.all, или последовательно при
зависимостях данных:
// Параллельные запросы
const [users, posts] = await Promise.all([
fetchJson('/users'),
fetchJson('/posts')
]);
// Последовательные запросы
const user = await fetchJson('/users/1');
const posts = await fetchJson(`/posts?userId=${user.id}`);
Отличие подходов:
При работе с API часто требуется авторизация. Заголовки передаются
через объект headers:
fetch('https://api.example.com/protected', {
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Accept': 'application/json'
}
})
.then(res => res.json())
.then(data => console.log(data));
Особенности:
Bearer используется для токенов OAuth.Basic подходит для базовой HTTP-аутентификации.Content-Type важна для правильной
отправки данных.Для загрузки файлов или отправки форм используется
FormData:
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'John');
fetch('https://api.example.com/upload', {
method: 'POST',
body: formData
})
.then(res => res.json())
.then(data => console.log(data));
Особенности:
FormData автоматически устанавливает заголовок
Content-Type с границей multipart.Fetch поддерживает управление кэшированием через опцию
cache:
default — стандартное поведение браузера.no-cache — проверяет сервер перед использованием
кэшированных данных.reload — всегда загружает заново.force-cache — использует только кэш, игнорируя
сервер.only-if-cached — возвращает только кэшированные данные,
иначе ошибка.fetch('/data', { cache: 'no-cache' });
Эта функциональность полезна для контроля свежести данных и оптимизации производительности.