Как обрабатывать JSON ответ в JavaScript
Что проверяют
Знаете ли вы путь от запроса до данных и что ломается на каждом шаге. Главная проверка: понимаете ли вы, что fetch не бросает ошибку на 404 и 500, и умеете ли не доверять ответу сервера. Следом часто просят разобрать ошибку парсинга или отмену запроса.
Как отвечать
- запрос и статус:
fetchотклоняет промис только при сетевой ошибке или отмене. Ответ404или500приходит как обычныйResponse, поэтому сначала проверяетсяresponse.ok(статус 200-299), и только потом разбирается тело; - парсинг:
await response.json()читает тело и разбирает его как JSON. Тело читается один раз, повторный вызов броситTypeError. На пустом ответе204или на HTML-странице ошибки от прокси парсинг упадёт сSyntaxError, поэтому полезно смотретьContent-Type; - ручной разбор:
JSON.parse(text)для строки, всегда вtry/catch. Второй аргументreviverпозволяет, например, превратить строки дат вDate; - валидация: тип TypeScript на результате
response.json()ничего не проверяет в рантайме. Ответ внешнего API валидируют схемой (Zod, Valibot) и получают понятную ошибку вместоundefinedглубоко в компоненте; - подводные камни формата: даты приходят строками, целые больше
Number.MAX_SAFE_INTEGERтеряют точность (идентификаторы лучше передавать строками), аundefinedи функции приJSON.stringifyпропадают; - отмена и таймаут:
AbortControllerилиAbortSignal.timeout(ms), чтобы ответ устаревшего запроса не перезаписал свежие данные.
В реальном приложении такую обёртку пишут один раз, а в компонентах используют через TanStack Query, SWR или свой хук, где уже есть состояния загрузки и ошибки.
Где спотыкаются
Не проверяют response.ok и пытаются разобрать страницу ошибки как JSON. В консоли появляется загадочное Unexpected token '<'.
Обрабатывают ошибку одним console.error. Пользователь видит вечный спиннер, потому что состояние ошибки в интерфейс не выведено.
Путают JSON.parse и response.json() и вызывают JSON.parse на уже разобранном объекте: он превращается в строку [object Object], и парсинг падает на ровном месте.