webroad.online
  1. 1Веб
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Инструменты
  8. 8React
  9. 9Стейт-менеджмент
  10. 10Next.js
  11. 11Формы
  12. 12Данные и бэкенд
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Анимации
  16. 16Тестирование
  17. 17Архитектура
JavaScript · Урок 15 из 17

fetch, JSON и AbortController

Правильные запросы, проверка res.ok, query-параметры и отмена.

Обновлено

Что такое fetch

fetch — нативная функция (в браузере, Node и Next) для HTTP-запросов: запросить данные у сервера или отправить их на сервер. Возвращает Promise с объектом Response.

const res = await fetch('/api/posts')
const posts = await res.json()

Два await: первый ждёт заголовки ответа, второй читает и разбирает тело.

Ловушка №1: fetch не бросает ошибку на 404 / 500

fetch бросает ошибку только при сетевых проблемах (офлайн, DNS, CORS). Ответ 404 или 500 для него — нормальный ответ.

const res = await fetch('/api/posts')
if (!res.ok) throw new Error(`HTTP ${res.status}`)   // res.ok = статус 200–299
const posts = await res.json()

Объект Response

Свойство / метод Что даёт
res.ok true для 2xx
res.status 200, 404…
res.headers.get('content-type') заголовок
res.json() тело, разобранное как JSON (Promise)
res.text() тело как текст
res.blob() файл / изображение

Тело можно прочитать только один раз.

Виды запросов

Нужно... Как
прочитать fetch(url) — по умолчанию GET
отправить JSON method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data)
отправить форму / файл method: 'POST', body: new FormData(form) — без Content-Type, его поставит браузер
изменить / удалить method: 'PATCH' / 'DELETE'
отправить cookie на другой домен credentials: 'include'
await fetch('/api/posts', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ title: 'Привет' }),
})

Что такое JSON

JSON (JavaScript Object Notation) — текстовый формат, в котором данные ходят между браузером и сервером. Похож на объект JS, но это строка со строгими правилами: ключи в двойных кавычках, без функций, без undefined, без запятой в конце.

JSON.stringify({ a: 1, d: new Date() })  // '{"a":1,"d":"2026-10-08T..."}' — Date становится строкой
JSON.parse('{"a":1}')                    // { a: 1 } — бросает SyntaxError на невалидном JSON

URL с параметрами

const url = new URL('/api/search', location.origin)
url.searchParams.set('q', 'next js')   // автоматическое кодирование: q=next+js
url.searchParams.set('page', '2')
fetch(url)

Не склеивайте вручную — символы вроде &, ?, пробела ломают URL.

Отмена и таймаут через AbortController

Старый запрос, ответивший после нового (поиск при вводе), может перезаписать правильный результат — это состояние гонки. Решение: отменить старый запрос.

const controller = new AbortController()
fetch(url, { signal: controller.signal })
controller.abort()                                  // запрос бросает AbortError

fetch(url, { signal: AbortSignal.timeout(5000) })   // автоматическая отмена через 5 с

Хелпер, написанный один раз

async function api(path, init) {
  const res = await fetch(path, init)
  if (!res.ok) throw new Error(`${res.status} ${res.statusText}`)
  return res.status === 204 ? null : res.json()
}

fetch в Next.js

В Server Components fetch выполняется на сервере (API-ключи остаются секретными). В Client Components для серверных данных лучше TanStack Query, чем fetch в useEffect.

Коротко

  • fetch → Response; проверьте res.ok, затем res.json().
  • JSON = текст; stringify при отправке, parse (или res.json()) при получении.
  • URL + searchParams для параметров; AbortController для отмены.

Официальные источники

Упражнения

Была ли страница полезной?

Один клик — без регистрации.