JavaScript WindowsLinuxmacOS

JavaScript: fetch возвращает ответ, но json() завершается SyntaxError

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

fetch получил HTTP-ответ, но response.json() выбрасывает SyntaxError: проверьте статус, Content-Type, тело ответа и двойное чтение потока, не подавляя ошибки разбора.

В этой статье
  1. Что происходит и как распознать неисправность
  2. Как отличить причины
  3. Пошаговая диагностика и исправление
  4. Команды и примеры для проверки
  5. Как проверить результат и что делать дальше

#Что происходит и как распознать неисправность

В отличие от Failed to fetch, здесь сетевой запрос завершился и объект Response получен. Метод .json() читает тело и разбирает его как JSON; SyntaxError означает неверный формат тела: HTML ошибки, пустой ответ, повреждённая JSON-строка либо неверные кавычки.

#Как отличить причины

Возможная причинаКак узнатьЧто делать
В ответе HTML вместо JSONПрокси или сервер вернул страницу входа/ошибки.В «Ответ» начинается <!doctype html> или <html>.Проверяйте status и Content-Type до разбора.
Ответ без телаСервер отправил 204 No Content либо пустую строку.В «Сеть» нет тела ответа.Не вызывайте json() для ожидаемо пустого ответа.
Сервер возвращает некорректный JSONСтрока содержит лишнюю запятую, комментарий, обрезанные байты.Во вкладке Response видна строка, нарушающая JSON.Исправьте сериализацию на стороне API.

#Пошаговая диагностика и исправление

  1. Воспроизведите запрос и откройте сетевые сведенияОткройте страницу, нажмите F12 → вкладка «Сеть», повторите действие, выберите нужный запрос fetch/XHR. Посмотрите код статуса и вкладку «Ответ». Если запроса нет или он заблокирован CORS, сначала устраните сетевую ошибку — этот материал относится только к полученному ответу.
  2. Отличите успешный HTTP от ответа с ошибкойВ строке запроса проверьте Status: 200, 204, 401, 404 или 500. fetch не отклоняет промис автоматически на HTTP 4xx/5xx; проверять response.ok нужно в вашем коде. Если статус 302 и затем HTML входа, решайте вопрос авторизации, а не парсинга JSON.
  3. Проверьте MIME-тип и первые символы телаВо вкладке «Заголовки» найдите Response Headers → Content-Type. Для JSON ожидается application/json или совместимый тип. В «Ответ» посмотрите начало содержимого: < указывает на HTML, пустота — на отсутствие тела. Если ответ содержит чувствительные данные, не выкладывайте его целиком в переписку.
  4. Отладьте тело без повторного чтенияВ тестовом обработчике получите const text = await response.clone().text() до response.json() — clone создаёт вторую ветвь потока. Выведите первые безопасные символы/длину, но не токены, пароль или личные данные. Не вызывайте сначала response.text(), а затем response.json() на том же объекте: поток читается один раз.
  5. Обработайте пустые успешные ответыЕсли API по контракту возвращает 204 No Content, проверяйте response.status === 204 и завершайте обработку без json(). Если по контракту должен быть JSON, попросите разработчика сервера отдавать корректное тело и Content-Type; не преобразовывайте пустую строку в фиктивный объект для всех ситуаций.
  6. Почините генерацию JSON на сервереЕсли сервер ваш, откройте обработчик маршрута и убедитесь, что он сериализует объект средствами языка (например, json_encode в PHP) и не печатает предупреждения, HTML или лишние пробелы перед JSON, где это важно для контракта. Проверьте ошибку на тестовом окружении; важные сведения об исключениях держите в серверных журналах, а не в клиентском ответе.
  7. Проверьте исправление и обработку неуспехаПерезагрузите страницу и повторите запрос. Ожидается валидный JSON, успешно обработанный await response.json(). Отдельно проверьте 204, 401 и ошибку 500: интерфейс должен показывать понятное сообщение. При регрессии восстановите прежний клиентский обработчик и передайте разработчику API код статуса и тип ответа.

#Команды и примеры для проверки

Текст
Передайте настоящий URL вашего API, например loadData("/api/items"). Пример показывает различение пустого ответа, HTTP-ошибки и JSON; нет обхода ошибок или двойного чтения.
async function loadData(url) {
  const response = await fetch(url);
  if (response.status === 204) return null;
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const kind = response.headers.get("content-type") || "";
  if (!kind.includes("json")) throw new Error("Сервер вернул не JSON");
  return response.json();
}

#Как проверить результат и что делать дальше

Если тело валидно и содержит ожидаемую структуру, JSON читается без SyntaxError. Если ошибка сохраняется, храните минимальный обезличенный образец ответа и сверяйте схему API; не выводите в лог секреты пользователя.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.