Fetch: примеры (JAVASCRIPT)
fetch(input: String|Request, [init]: Object): PromiseОписание функции fetch
Функция fetch() в JavaScript предоставляет современный интерфейс для выполнения HTTP-запросов. Она используется для взаимодействия с сетевыми ресурсами, заменяя устаревший XMLHttpRequest. Функция возвращает Promise, который разрешается в объект Response, представляющий ответ на запрос.
Основные аргументы функции:
- url (обязательный): строка или объект URL, указывающий на целевой ресурс.
- options (необязательный): объект конфигурации запроса, который может включать:
- method: метод HTTP (GET, POST, PUT, DELETE и другие).
- headers: объект с HTTP-заголовками.
- body: данные для отправки (для POST, PUT).
- mode: режим запроса (cors, no-cors, same-origin).
- credentials: управление учетными данными (include, same-origin, omit).
- cache: режим кеширования.
- redirect: обработка перенаправлений.
- referrerPolicy: политика передачи referrer.
- signal: объект AbortSignal для отмены запроса.
Возвращаемое значение: Promise, который разрешается в объект Response. Этот объект содержит информацию об ответе: статус, заголовки, а также методы для извлечения тела ответа в различных форматах (.json(), .text(), .blob() и другие).
Простые примеры запросов
Пример GET-запроса с обработкой JSON-ответа:
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Ошибка:', error));// В консоли выводится полученный объект данных.
Пример POST-запроса с передачей JSON-данных:
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'John', age: 30 })
})
.then(response => response.json())
.then(data => console.log(data));// Ответ сервера после обработки данных.
Запрос с проверкой статуса ответа:
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Сетевая ошибка: ' + response.status);
}
return response.json();
})
.then(data => console.log(data));// Если ответ успешный, данные выводятся в консоль.
Альтернативные средства в JavaScript
XMLHttpRequest (XHR): устаревший, но поддерживаемый способ асинхронных запросов. Отличается более сложным API на основе событий. Применяется в legacy-коде.
Библиотека Axios: популярная сторонняя библиотека. Автоматически преобразует данные в JSON, имеет встроенную обработку ошибок и отмену запросов. Подходит для сложных проектов.
jQuery.ajax(): метод из библиотеки jQuery. Упрощает запросы в проектах, где уже используется jQuery, но считается устаревшим для новых приложений.
Выбор зависит от требований проекта. Для современных приложений fetch является стандартным решением, в то время как Axios предлагает дополнительные удобства.
Сетевые запросы в других языках
Python (библиотека requests): синхронный и более простой API по сравнению с fetch.
import requests
response = requests.get('https://api.example.com/data')
data = response.json()# data содержит ответ в формате словаря.
PHP (функция file_get_contents): простая загрузка содержимого, но с ограниченными возможностями для сложных запросов.
$data = file_get_contents('https://api.example.com/data');
$decoded = json_decode($data);// $decoded содержит объект или массив.
C (библиотека libcurl): низкоуровневый контроль над запросами, но с более сложным кодом. Примеры обычно многострочные.
MySQL: не предназначен для внешних HTTP-запросов, для этого используются хранимые процедуры с дополнительными плагинами или внешние программы.
Распространенные ошибки
Отсутствие обработки ошибок сети и статусов ответа. Функция fetch не отклоняет Promise при статусах 4xx/5xx, только при сбоях сети.
fetch('https://api.example.com/notfound')
.then(response => response.json()) // Ошибка, если статус 404
.catch(error => console.error(error));// Uncaught (in promise) SyntaxError: Unexpected token...
Использование ответа несколько раз. Тело ответа может быть прочитано только один раз.
fetch('https://api.example.com/data')
.then(response => {
const text = response.text(); // Потребляет поток
const json = response.json(); // Ошибка: тело уже прочитано
});// TypeError: Body is already used
Отправка неправильных заголовков, особенно для JSON-данных.
fetch('/api', {
method: 'POST',
body: JSON.stringify({ data: 1 })
// Заголовок Content-Type не установлен
});// Сервер может не распознать данные.
Обновления и изменения
С момента внедрения в стандарт ES2015, функция fetch получила несколько важных дополнений:
- Поддержка объекта
AbortControllerи интерфейсаAbortSignalдля отмены запросов. - Расширение возможностей объекта
RequestиResponse. - Улучшения в обработке потоков данных и кешировании.
- Большинство современных браузеров теперь полностью поддерживают базовый функционал, хотя некоторые расширенные опции могут требовать проверки.
Расширенные сценарии работы
Отправка данных формы с файлом с использованием FormData:
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'test');
fetch('https://api.example.com/upload', {
method: 'POST',
body: formData
// Заголовок Content-Type устанавливается автоматически
});// Файл и данные отправлены на сервер.
Параллельное выполнение нескольких запросов с помощью Promise.all:
const urls = ['/api/data1', '/api/data2'];
Promise.all(urls.map(url => fetch(url).then(res => res.json())))
.then(results => {
console.log(results[0], results[1]);
});// Массив с результатами всех запросов.
Использование AbortController для отмены запроса:
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
.then(response => response.json())
.catch(err => {
if (err.name === 'AbortError') {
console.log('Запрос отменен');
}
});
// Для отмены: controller.abort();// Если запрос отменен, будет выведено сообщение.
Работа с режимом 'no-cors' для запросов к другим источникам, когда сервер не возвращает CORS-заголовков:
fetch('https://another-site.com/data', {
mode: 'no-cors'
})
.then(response => {
// Response будет 'opaque'
console.log(response.type); // 'opaque'
});// Получен ответ с ограниченной информацией.