Fetch
JavaScript может отправлять сетевые запросы на сервер и подгружать новую информацию по мере необходимости.
Например, мы можем использовать сетевой запрос, чтобы:
- Отправить заказ,
- Загрузить информацию о пользователе,
- Запросить последние обновления с сервера,
- …и т.п.
Для сетевых запросов из JavaScript есть широко известный термин «AJAX» (аббревиатура от Asynchronous JavaScript And XML). XML мы использовать не обязаны, просто термин старый, поэтому в нём есть это слово. Возможно, вы его уже где-то слышали.
Есть несколько способов делать сетевые запросы и получать информацию с сервера.
Метод fetch() — современный и очень мощный, поэтому начнём с него. Он не поддерживается старыми (можно использовать полифил), но поддерживается всеми современными браузерами.
- url – URL для отправки запроса.
- options – дополнительные параметры: метод, заголовки и так далее.
Без options это простой GET-запрос, скачивающий содержимое по адресу url .
Браузер сразу же начинает запрос и возвращает промис, который внешний код использует для получения результата.
Процесс получения ответа обычно происходит в два этапа.
Во-первых, promise выполняется с объектом встроенного класса Response в качестве результата, как только сервер пришлёт заголовки ответа.
На этом этапе мы можем проверить статус HTTP-запроса и определить, выполнился ли он успешно, а также посмотреть заголовки, но пока без тела ответа.
Промис завершается с ошибкой, если fetch не смог выполнить HTTP-запрос, например при ошибке сети или если нет такого сайта. HTTP-статусы 404 и 500 не являются ошибкой.
Мы можем увидеть HTTP-статус в свойствах ответа:
- status – код статуса HTTP-запроса, например 200.
- ok – логическое значение: будет true , если код HTTP-статуса в диапазоне 200-299.
Во-вторых, для получения тела ответа нам нужно использовать дополнительный вызов метода.
Response предоставляет несколько методов, основанных на промисах, для доступа к телу ответа в различных форматах:
- response.text() – читает ответ и возвращает как обычный текст,
- response.json() – декодирует ответ в формате JSON,
- response.formData() – возвращает ответ как объект FormData (разберём его в следующей главе),
- response.blob() – возвращает объект как Blob (бинарные данные с типом),
- response.arrayBuffer() – возвращает ответ как ArrayBuffer (низкоуровневое представление бинарных данных),
- помимо этого, response.body – это объект ReadableStream, с помощью которого можно считывать тело запроса по частям. Мы рассмотрим и такой пример несколько позже.
Например, получим JSON-объект с последними коммитами из репозитория на GitHub:
XMLHttpRequest против Fetch API: что лучше для отправки Ajax в 2019 году?
В марте 2019 года будет юбилей, 20-летие Ajax. Первая реализация XMLHttpRequest была выпущена в 1999 году как компонент ActiveX IE5.0.
До этого существовали способы извлечения данных с сервера без полного обновления страницы, но они часто полагались на неуклюжие методы, такие как внедрение script или сторонние плагины. Microsoft разработала первичную версию XMLHttpRequest для браузерной альтернативы своему почтовому клиенту Outlook.
XMLHttpRequest не был веб-стандартом до 2006 года, но он был реализован в большинстве браузеров. Его принятие в Gmail (2004) и Google Maps (2005) привело к появлению в 2005 году статьи Джесси Джеймса Гарретта AJAX: новый подход к веб-приложениям. Новый термин кристаллизуется в центре внимания разработчиков.
AJAX для Ajax
AJAX — это мнемоника Asynchronous JavaScript and XML. “Асинхронный” определенно, но:
- Выбран JavaScript, хотя были и другие варианты, VBScript и Flash
- Полезная нагрузка не должна была быть в формате XML, хоть это и было популярно в то время. Сегодня обычно предпочтительнее использовать JSON.
Теперь мы используем «Ajax» в качестве общего термина для любого процесса на стороне клиента, который извлекает данные с сервера и динамически обновляет DOM без полного обновления страницы. Ajax — это основной метод для большинства веб-приложений и одностраничных приложений (SPA).
Экстремальный XMLHttpRequest
Следующий код JavaScript показывает базовый HTTP-запрос GET для http://domain/service с использованием XMLHttpRequest (обычно сокращается до XHR):
Объект XMLHttpRequest имеет много других параметров, событий и свойств ответа. Например, тайм-аут в миллисекундах может быть установлен и обнаружен:
и событие progress может сообщить о длительной загрузке файла:
Число параметров может вызывать недоумение, и ранние реализации XMLHttpRequest имели несколько кросс-браузерных несоответствий. По этой причине большинство библиотек и сред предлагают функции-оболочки Ajax для решения этих проблем, например, метод jQuery.ajax():
Быстрая перемотка Fetch
Fetch API является современной альтернативой XMLHttpRequest. Универсальные интерфейсы Headers, Request и Response обеспечивают согласованность, в то время как Promises позволяют упростить цепочки и async/await без обратных вызовов. Приведенный выше пример XHR можно преобразовать в гораздо более простой код на основе Fetch, который даже анализирует возвращенный JSON:
Fetch — чистый, элегантный, простой для понимания и интенсивно используемый в PWA Service Workers. Почему бы вам не использовать его вместо древнего XMLHttpRequest?
К сожалению, веб-разработка никогда не бывает такой четкой. Fetch еще не является полноценной заменой методов Ajax…
Поддержка браузера
Fetch API достаточно хорошо поддерживается, но он не будет работать во всех выпусках Internet Explorer. Люди, использующие версии Chrome, Firefox и Safari старше 2017 года, также могут испытывать проблемы. Эти пользователи могут составлять небольшую часть ваших пользователей. или это может быть основной клиент. Всегда проверяйте, прежде чем начать кодирование!
Cookieless по умолчанию
В отличие от XMLHttpRequest, не все реализации Fetch будут отправлять куки-файлы, поэтому аутентификация вашего приложения может быть неудачной. Проблема может быть исправлена путем изменения параметров инициации, передаваемых во втором аргументе, например:
Ошибки не отклоняются
Удивительно, но ошибка HTTP, такая как 404 Page Not Found или 500 Internal Server Error, .catch() никогда не запускается. Обычно он разрешается с состоянием response.ok, установленным в false.
Отказ происходит только в том случае, если запрос не может быть выполнен, например, сбой сети. Это может усложнить реализацию перехвата ошибок.
Тайм-ауты не поддерживаются
Fetch не поддерживает тайм-ауты, и запрос будет продолжаться до тех пор, пока браузер его обрабатывает. Для того, чтобы обернуть выборку в другое обещание, требуется дополнительный код, например:
…или, возможно, используйте Promise.race()
Отмена в Fetch
Запрос XHR легко завершить с помощью xhr.abort() и, при необходимости, обнаружить такое событие с помощью функции xhr.onabort.
Прекращение отправки было невозможно в течение нескольких лет, но теперь оно поддерживается в браузерах, которые реализуют API AbortController. Это запускает сигнал, который может быть передан объекту инициации Fetch:
Обработка может быть прервана вызовом controller.abort(). Promise отклоняет, поэтому вызывается функция .catch().
Нет прогресса
На момент написания, Fetch не поддерживает события прогресса. Поэтому невозможно сообщить о статусе загрузки файлов или аналогичных представлений больших форм.
XMLHttpRequest против Fetch API?
В конечном счете, выбор за вами. если только у вашего приложения нет клиентов использующих IE, которым требуются индикаторы загрузки.
Для простых вызовов Ajax, XMLHttpRequest является более низким уровнем, более сложным, и вам потребуются функции-оболочки. К сожалению, то же самое произойдет и после того, как вы начнете учитывать сложность тайм-аутов, прерываний вызовов и отслеживания ошибок.
Вы можете выбрать Fetch полифил вместе с полифилом Promise, чтобы можно было писать код Fetch в IE. Тем не менее, XHR используется как запасной вариант; не каждый вариант будет работать так, как ожидалось, например, куки будут отправлены независимо от настроек.
Fetch это будущее. Тем не менее, API является относительно новым, он не обеспечивает все функциональные возможности XHR, а некоторые параметры являются громоздкими. Используйте его с осторожностью в течение следующих нескольких лет.
JavaScript Fetch API
![]()
Самым большим отличием Fetch от XMLHttpRequest является то, что первый использует промисы, которые значительно упрощают работу с запросами и ответами. Код на Fetch получается более простым и чистым.
Начиная с ES7, вы можете использовать async-await и полностью избавиться от обещаний.
Fetch API предоставляет глобальный метод fetch():
Отправка запроса и чтение ответа
Если не указывать метод, то Fetch API по умолчанию делает GET-запрос.
Метод fetch() возвращает promise. Для обработки результата можно использовать методы then() и catch() :
При успешном выполнении запроса, мы получим объект Response . У Response есть ряд полезных свойств для проверки состояния ответа:
- status – код статуса;
- statusText – текст статуса;
- ok – true , когда код статуса от 200 до 299;
- redirected – true , если при вызове запрошенного URL-адреса произошёл редирект.
Проверить, выполнен ли запрос успешно, можно с помощью свойства ok :
Промис ( request ) завершается успешно даже когда запрошенный URL не существует (код ответа 404) или он вызывает ошибку 500. Просто будут другие значения свойств: status , ok и т.д.
В метод catch мы попадём только в том случае, когда fetch() вообще не может выполнить запрос, т.е. нет такого сайта или произошла потеря сетевого соединения.
Для получения тела ответа, у объекта Response имеются следующие методы:
- text() – как текст;
- json() – в формате JSON;
- formData() – как объект FormData;
- blob() – в формате Blob;
- arrayBuffer() – как ArrayBuffer.
Все эти методы возвращают promise, который в конечном итоге выполняется и выводит содержимое.
Например, прочитаем ответ как строку и выведем её в элемент с id=»result» :
Вместо обещаний можно использовать async-await:
Пример использования fetch() для получения JSON
Напишем пример, в котором будем получать информацию о пользователях в формате JSON. Для того, чтобы запросить данные об конкретном пользователе будем брать значение из поля, а затем добавлять его в URL посредством GET-параметра id .

Содержимое файла «05.php», который возвращает данные о пользователях в формате JSON: