Что такое fetch в JavaScript
Что проверяют
Знаете ли вы, как fetch ведёт себя в неочевидных местах: ошибки HTTP, чтение тела, отмена запроса, CORS. Типичный уточняющий вопрос: попадёт ли ответ 404 в catch.
Как отвечать
fetch это встроенный API для HTTP-запросов на промисах. Он есть во всех браузерах, глобально доступен в Node.js с версии 18, а также в Deno и Bun. Вызов fetch(url, options) возвращает Promise<Response>.
Что важно назвать:
- ошибки: промис отклоняется только при сетевой ошибке, блокировке CORS или отмене. Ответ
404или500считается успешным, поэтому проверяютresponse.ok(статусы от 200 до 299) илиresponse.status; - тело: читается методами
json(),text(),blob(),formData(),arrayBuffer(), каждый возвращает промис. Тело читается один раз, для второго нуженresponse.clone(); - отправка:
method,headers,body. Для JSON тело сериализуют черезJSON.stringifyи ставятContent-Type: application/json; - куки:
credentialsпо умолчаниюsame-origin, для кросс-доменных запросов нуженincludeи разрешение со стороны сервера; - отмена и таймаут: встроенного таймаута нет, используют
AbortControllerилиAbortSignal.timeout(5000).
С async/await запрос читается проще: const res = await fetch(url); if (!res.ok) throw new Error(...); const data = await res.json();. Стоит упомянуть, чего у fetch нет по сравнению с axios: интерцепторов, автоматического разбора JSON и событий прогресса отправки. Прогресс скачивания при этом можно считать, читая response.body как поток. В Next.js серверный fetch дополнительно умеет кэширование через опцию next.
Где спотыкаются
Ждут, что 404 попадёт в catch, и не проверяют ok. Ошибка сервера уходит в разбор JSON и падает уже там, с непонятным сообщением.
Вручную ставят Content-Type при отправке FormData. Браузер сам проставляет его вместе с boundary, а ручной заголовок ломает разбор на сервере.
Лечат ошибку CORS режимом mode: 'no-cors'. Запрос уходит, но ответ становится непрозрачным: ни статуса, ни тела прочитать нельзя. CORS настраивается на сервере.