JavaScript Fetch API
Fetch API — современный интерфейс JavaScript для сетевых запросов. Гибкость, простота и расширенные возможности по сравнению с XMLHttpRequest.
Fetch API — ключевая возможность JavaScript, позволяющая выполнять сетевые запросы (загружать данные, отправлять формы, обращаться к API) и возвращающая Promise. Это современная замена устаревшему XMLHttpRequest, которая органично сочетается с async/await. В этом руководстве рассмотрены основные паттерны: GET- и POST-запросы, анализ ответа, чтение JSON и текста, отправка заголовков и обработка ошибок — с использованием бесплатного API JSONPlaceholder для запускаемых примеров.
Понимание Fetch API
Fetch API создан для сетевого взаимодействия и использует систему на основе промисов для получения ресурсов. Он достаточно гибок для работы с различными форматами данных и сложными запросами, что делает его отличным выбором при разработке веб-приложений.
Базовая сигнатура — fetch(url, options). Метод возвращает промис, который разрешается объектом Response сразу после того, как сервер ответил заголовками — ещё до завершения загрузки тела ответа. Тело читается отдельно с помощью таких методов, как .json() или .text(), каждый из которых возвращает собственный промис.
Важный нюанс: fetch() отклоняется только при сетевой ошибке (нет соединения, ошибка DNS, блокировка CORS). Он не отклоняется при HTTP-статусах, указывающих на ошибку, таких как 404 или 500 — в этих случаях промис успешно разрешается. Вам необходимо самостоятельно проверять response.ok (или response.status).
Базовое использование Fetch
Рассмотрим простой пример получения данных из поста JSONPlaceholder:
Этот фрагмент кода получает данные конкретного поста и демонстрирует, как Fetch возвращает промис, разрешающийся в ответ на запрос. Ответ затем парсится как JSON и выводится в консоль.
Анализ ответа
Объект Response содержит полезные метаданные ещё до чтения тела. Наиболее важные свойства:
response.ok— boolean, равныйtrueдля кодов состояния в диапазоне 200–299.response.status— числовой код состояния HTTP (например,200,404,500).response.statusText— текстовое сообщение, соответствующее коду состояния (например,"OK").response.headers— объектHeaders, к которому можно обратиться через.get().
Чтение тела: .json() и .text()
Тело ответа можно прочитать в нескольких форматах. Каждый метод возвращает промис и может быть вызван только один раз для каждого ответа — тело является потоком, который потребляется при чтении:
response.json()— парсит тело как JSON и разрешается в JavaScript object или array.response.text()— разрешается в необработанное тело в виде string. Удобно для простого текста, HTML или когда вы хотите самостоятельно обработать парсинг JSON.response.blob()— разрешается в объектBlob, для бинарных данных, например изображений или файлов.
Обработка ошибок в Fetch
Обработка ошибок критически важна при работе с сетевыми запросами. Поскольку fetch() не выбрасывает исключение при HTTP-статусах ошибок, стандартный паттерн — проверять response.ok и выбрасывать собственную ошибку, когда это значение равно false. Пример с обработкой ошибок:
В этом примере мы проверяем успешность ответа; если ответ неуспешен, выбрасывается ошибка. Метод .catch() перехватывает любые ошибки, сохраняя целостность приложения.
Выполнение POST-запроса
Fetch API не ограничен GET-запросами — он одинаково хорошо справляется с POST-запросами для отправки данных на сервер. Передайте второй аргумент с method, body и headers. При отправке JSON необходимо как сериализовать тело с помощью JSON.stringify(), так и установить заголовок Content-Type, чтобы сервер знал, как его парсить. Вот как создать новый пост в JSONPlaceholder:
Этот фрагмент кода демонстрирует отправку POST-запроса с данными в формате JSON, с указанием метода, тела и заголовков. Он показывает универсальность Fetch API при работе с различными типами запросов.
Отправка пользовательских заголовков запроса
Заголовки — это способ сообщить серверу о запросе: тип содержимого, ожидаемый формат ответа или учётные данные для аутентификации, например bearer-токен. Заголовки можно передать как обычный object или создать с помощью класса Headers для большего контроля:
Примечание: запрос к другому источнику будет успешным только в том случае, если этот сервер разрешает его через CORS. Смотрите Fetch: Cross-Origin Requests, чтобы узнать, как правила cross-origin влияют на заголовки и учётные данные.
Использование Async/Await с Fetch
Для более элегантного подхода к асинхронному коду Fetch API можно комбинировать с async и await. Этот метод обеспечивает более читаемый синтаксис, схожий с синхронным кодом:
Используя async и await, этот пример получает пост, ожидая ответа и обрабатывая его внутри блока try/catch для обработки ошибок. Он демонстрирует, как современные возможности JavaScript могут упростить использование Fetch API.
Обработка ошибок с Async/Await
При обработке ошибок в async/await обычно используются блоки try-catch.
Чтобы обрабатывать ошибки, которые могут возникнуть во время асинхронных операций, оберните вызовы await в блок try и перехватывайте возникшие ошибки блоком catch. Вот как можно добавить обработку ошибок в функцию fetchData:
Распространение ошибок
Распространение ошибок — это то, как ошибка «перемещается» или передаётся из одной части программы в другую. Представьте это как путь, который ошибка проходит после возникновения. Когда происходит ошибка, это похоже на падение мяча. Распространение ошибок — это то, куда мяч катится после падения: кто-то его поймает, или он упадёт на землю?
В JavaScript это обычно происходит через цепочку отклонения промисов, где необработанное отклонение поднимается по стеку вызовов до тех пор, пока его не перехватит блок catch или глобальный обработчик.
В приведённом ниже примере, если вы хотите, чтобы ошибки обрабатывались вызывающей функцией (например, viewData), следует либо не перехватывать их в fetchData, либо повторно выбрасывать после перехвата:
Как видите, один и тот же объект ошибки перехватывается в обеих функциях, поскольку мы повторно выбрасываем его из fetchData в viewData.
Связанные темы
Чтобы углубиться в изучение Fetch API, ознакомьтесь со связанными главами:
- JavaScript Promise — основа, на которой построен Fetch.
- Async/Await — самый удобный способ написания Fetch-вызовов.
- Fetch: Abort — отмена запроса с помощью
AbortController(полезно для таймаутов и поиска по мере ввода). - Fetch: Cross-Origin Requests — как CORS контролирует запросы к другим доменам.
Заключение
Fetch API — незаменимый инструмент для JavaScript-разработчиков, обогащающий веб-приложения благодаря подходу к сетевым запросам на основе промисов. На практических примерах это руководство демонстрирует, как Fetch API можно эффективно использовать для получения данных, обработки ошибок и выполнения POST-запросов с применением JSONPlaceholder API для реальных приложений. Владение Fetch API позволяет разработчикам создавать более отзывчивые, динамичные и надёжные веб-приложения.