#Что означает ошибка
SyntaxError: Unexpected token in JSON at position 0 (is not valid JSON)
SyntaxError: Unexpected token < in JSON at position 0 (или Unexpected token '<', Unexpected end of JSON input) возникает при JSON.parse() или response.json(), когда вместо JSON пришёл другой текст. Символ < в начале говорит, что вернулась HTML-страница, чаще страница ошибки 404/500.
Проблема не в парсере, а в ответе сервера.
Посмотрите реальное тело ответа.
Ошибка означает, что вместо JSON сервер вернул HTML (чаще всего страницу ошибки или авторизации). Проверьте ответ в сетевой вкладке: адрес, статус и заголовок Content-Type.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Сервер вернул HTML | Страница ошибки. | Проверьте адрес и статус. |
| Неверный URL запроса | 404. | Исправьте. |
| Редирект на страницу входа | Авторизация. | Проверьте сессию. |
| Некорректный JSON | Ошибка сервера. | Исправьте на сервере. |
#Пошаговое решение
- Откройте Network и ResponseВ Chrome/Edge/Firefox откройте F12 → вкладка Network («Сеть»), воспроизведите ошибку и найдите запрос к API по адресу/методу. Откройте вкладку Response («Ответ»): если там HTML (
<!doctype html>,<html>), страница входа или сообщение прокси, такой текст нельзя разобрать как JSON. Если вы вручную вызываетеJSON.parse, временно выведите на экран не секретные первые символы исходной строки. Не публикуйте в журнале токены, персональные данные и полный ответ API. - Проверьте статус и URL запросаВо вкладке Headers («Заголовки») посмотрите фактические Request URL, Status Code и наличие Redirect (возможен переход на страницу входа). Код 404 обычно означает неверный маршрут, 500 — ошибку сервера, 401/403 — проблему доступа; даже ответ 200 может оказаться HTML-страницей входа. Для API с относительным адресом проверьте базовый URL, префикс
/apiи настройку прокси сервера разработки. Исправлять JSON-парсер бессмысленно, пока сервер отдаёт неправильный документ. - Выведите r.text() перед r.json()Если это ваш JavaScript, проверьте текст ответа через
const text = await response.text()вместоresponse.json()в одной диагностической попытке: тело ответа можно прочитать только один раз. В безопасном тестовом запросе выведитеtext.slice(0,200)и проверьте начало строки; затем верните нормальную обработку. Для повторного чтения воспользуйтесьresponse.clone().text()доresponse.json()либо сделайте новый запрос. ПриUnexpected endобратите внимание на пустое тело, например при HTTP 204: такой ответ нельзя парсить как JSON. - Проверьте заголовок Content-TypeВо вкладке Headers проверьте
Content-Type, ожидаемый для JSON — обычноapplication/json(возможен параметрcharset). Сначала убедитесь, чтоresponse.okистинен, а тело не пустое; затем вызывайтеresponse.json(). Если сервер неожиданно прислал ошибку HTML, показывайте пользователю сообщение о запросе и логируйте статус на сервере.Content-Typeсам по себе не гарантирует валидный JSON — проверьте фактическое содержимое. - Проверьте серверный вывод на предупреждения и BOMЕсли API ваш, откройте журналы сервера в панели хостинга или через администратора, найдите запись по времени/URL запроса. Убедитесь, что обработчик возвращает корректный JSON без PHP-предупреждений, HTML-страниц авторизации и побочного вывода; для PHP проверьте
json_encode()и отдельный журнал ошибок. Запуститеcurl -iс реальным URL своего API, сравните HTTP-статус, Content-Type и тело; если CORS-сценарий, дополнительно проверьте в браузере. После исправления повторите запрос и разбор JSON безSyntaxError.
#Что пришло на самом деле
В DevTools (F12 → Network) откройте запрос и вкладку Response: если там HTML, проверьте статус и URL. Частые причины: неверный путь к API (404), редирект на страницу входа, ошибка сервера (500 с HTML), CORS-страница, прокси вернул страницу-заглушку, dev-сервер отдал index.html для неизвестного маршрута. Выведите текст: const t = await r.text(); console.log(t.slice(0,200));.
#Проверки в коде
Проверяйте статус: if (!r.ok) throw new Error(r.status), и тип: r.headers.get("content-type") должен содержать application/json. Для Unexpected end of JSON input тело пустое: ответ 204 или обрезан. Для Unexpected token o in JSON вы парсите уже готовый объект ([object Object]): уберите лишний JSON.parse. Для строк с одинарными кавычками, комментариями и висячими запятыми используйте валидатор .
#Серверная сторона
Убедитесь, что сервер отправляет заголовок Content-Type: application/json и валидный JSON; PHP-предупреждения перед echo json_encode() ломают ответ (выключите вывод ошибок в продакшене, смотрите журнал). Проверьте BOM в начале файла и лишние пробелы до <?php. Проверьте, что маршрут API не перехвачен SPA-фоллбэком (try_files в nginx). Проверьте запрос командой curl -i URL.
# Только диагностика публичного или своего API; замените URL своимcurl -i https://example.com/api/items