Самоучитель: динамические веб-приложения
Глава 14 из 18VI. Браузер как приложение100 минут

Глава 14. Fetch и JSON API как согласованный контракт

Клиент и сервер заранее договариваются о методе, схеме JSON, статусах и повторе; fetch лишь переносит этот контракт через сеть.

После главы вы сможете
  • проверять Response
  • проектировать error shape
  • управлять повтором команды

Fetch завершается на заголовках

Promise fetch разрешается после получения заголовков даже для 404 и 500. Сначала проверьте response.ok и Content-Type, затем читайте тело один раз выбранным методом. Попытка вызвать json() и text() последовательно не сработает: поток уже использован.

Сетевой отказ, отмена и HTTP-ошибка требуют разных сообщений и решений. Не обещайте пользователю, что команда не выполнена, если соединение оборвалось после отправки тела.

Клиентский адаптер

export async function createTask(input, signal) {
  const response = await fetch('./api/tasks', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(input),
    signal
  });

  const payload = await response.json();
  if (!response.ok) throw new ApiError(response.status, payload);
  return payload;
}

Стабильная форма ошибки

Опишите машинный code, понятный message, список ошибок полей и correlation id. Не отдавайте имя класса исключения или SQL. Статус остаётся главным сигналом протокола, а code различает предметные причины внутри одного статуса.

Схема ответа версионируется так же, как вход. Добавление необязательного поля обычно совместимо, переименование и смена типа требуют перехода.

Повтор и идемпотентность

Безопасный повтор командыIdempotency key позволяет отличить повтор той же команды от нового намерения пользователя.ClientkeyAPIvalidateStorereserveUse caseexecuteReplaysame result
Idempotency key позволяет отличить повтор той же команды от нового намерения пользователя.

CORS и credentials

Same-origin запрос не требует CORS. Для отдельного origin сервер отвечает конкретным Access-Control-Allow-Origin и Vary: Origin; credentialed запрос также требует явного allow-credentials и не совместим с wildcard origin. Preflight OPTIONS не должен выполнять предметное действие.

Если архитектура позволяет, один origin для страницы и API уменьшает конфигурацию и число ошибок. CORS — политика чтения браузера, а не межсерверная аутентификация.

Optimistic UI с обратным ходом

Мгновенно показывайте предсказуемое изменение только тогда, когда можно надёжно отменить его или пометить pending. Сервер остаётся источником истины. При конфликте версии верните актуальное состояние и предложите пользователю повторить решение, а не молча перезаписывайте.

Не добавляйте автоматический retry ко всем POST. Повтор разрешён контрактом идемпотентности либо явной командой пользователя.

Практика главы

Создайте API завершения задачи и JS-адаптер. Опишите 200, 401, 403, 404, 409 и сетевой сбой. Добавьте AbortController для чтения списка и idempotency key для создания.

Локальный прогресс

Закрепите материал

Отметка, заметка, чек-лист и ответы остаются в localStorage этого браузера и не отправляются в аналитику.

Перелинковка со справочником

Проверка актуальности

  • developer.mozilla.orghttps://developer.mozilla.org/en-US/docs/Web/API/Fetch_APIПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
  • developer.mozilla.orghttps://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORSПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.

Текст и схемы созданы для этого самоучителя без воспроизведения страниц, иллюстраций и листингов приложенной книги. Проверено: .

Данные этого сервиса

Настройки cookie и локальных данных

Аналитика

Текущий статус: не выбран. До согласия обе аналитические системы не загружаются.

Локальные данные

Удаление затрагивает только ключи PHP-сервиса в этом браузере и требует подтверждения.

Политики

Политика конфиденциальности · Политика использования файлов cookie