JSON Toolkit

Як виправити помилки розбору JSON: покроковий розбір Unexpected token

Головне: Перетворіть помилки JSON.parse на рядок і символ, а потім виключіть шість причин: висячі коми, одинарні лапки, коментарі, керівні символи, BOM і обрізання.

Початковий~12 хв читанняОпубліковано 2026-10-30Оновлено 2026-11-01
Обкладинка статті про діагностику помилок розбору JSON

Коротко: під час помилки розбору прочитайте вказані рядок і стовпець, щоб знайти перший недопустимий символ, а далі визначте, це пропущена лапка, пропущена кома, висяча кома, BOM чи обрізання — не перечитуйте весь документ з початку.

Повідомлення про помилку ніколи не каже «що саме не так»; воно лише каже «де парсер більше не зміг продовжити». Ці дві позиції часто не збігаються.

1. Спершу перетворіть помилку на координати

Той самий зламаний JSON дає цілком різні помилки в різних мовах, але всі їх можна перевести в «який рядок, який символ»:

Середовище Типова помилка Як її читати
Браузер / Node Unexpected token } in JSON at position 42 position — це відступ символу від нуля, а не номер рядка
Node 20+ Unexpected non-whitespace character after JSON at position 42 означає, що перша частина валідна, а зайвий вміст починається після 42
Java Jackson Unexpected character ('}' (code 125)): was expecting ... at [Source: (String)..."..." ; line: 3, column: 1] дає рядок і стовпець одразу, найзручніше з усіх
Python json.decoder.JSONDecodeError: Expecting ',' delimiter: line 3 column 1 (char 42) char — це відступ; важливі рядок і стовпець
Go invalid character '}' looking for beginning of object key string дає лише символ, тож доводиться самостійно повертатися назад і шукати його

Коли маєте позицію, вставте JSON у онлайн-парсер JSON; інструмент ставить курсор на місце помилки й підсвічує номер рядка та стовпця — цей крок економить 90% вдивляння в символи.

2. Шість найчастіших помилок

1. Висяча кома

{
  "name": "json",
  "version": 1,
}

Перед } стоїть зайва кома. Специфікація JSON не дозволяє висячих ком, а об'єктні літерали JavaScript дозволяють, тож конфігурація, копійована з коду, найчастіше її містить. Виправлення: видаліть останню кому; якщо ці дані спершу живуть у JS-файлі, переходьте на конвертацію в JSON5, а не вганяйте їх у JSON силою.

2. Одинарні лапки й ключі без лапок

{ 'name': 'json' }
{ name: "json" }

Рядки JSON можуть використовувати лише подвійні лапки, а ключі теж мають бути рядками в подвійних лапках. Ці два випадки — послаблений синтаксис JSON5 / JavaScript, а не JSON. Подвійну лапку всередині рядка треба писати як \", а зворотну скісну риску — як \\.

3. Коментарі

{
  // Timeout in milliseconds
  "timeout": 3000
}

У граматиці RFC 8259 немає місця для коментарів. Або видаліть коментарі, або збережіть як .jsonc / .json5 і використовуйте парсер із підтримкою коментарів. Про компроміси між різними «схемами коментарів» дивіться Як писати коментарі в JSON.

4. Сирі переведення рядка й керівні символи всередині рядків

{"sql": "SELECT *
FROM t"}

Рядки JSON не можуть містити сирих переведень рядка, табуляцій чи керівних символів U+0000–U+001F; їх треба писати як \n, \t, \u0009. Коли вставляєте багаторядковий текст у JSON, спершу екрануйте його в редакторі або обробіть однаково через мініфікацію й екранування JSON.

5. Заголовок BOM

UTF-8, збережений Windows Notepad, містить три байти EF BB BF. JSON.parse повідомляє Unexpected token, коли натрапляє на BOM, а око його взагалі не бачить. Як визначити: перегляньте заголовок файлу в шістнадцятковому вигляді або копіюйте вміст в онлайн-інструмент і подивіться, чи перший символ показується як . Виправлення: збережіть як «UTF-8 без BOM».

6. Обрізаний вміст

Лог, що вивів лише перші 4096 символів, відповідь API, обрізана шлюзом, перерване завантаження — ознака цього класу: «помилка в кінці», а кількість дужок не збігається. Спершу порахуйте дужки: якщо закриття { і [ не збігаються, це обрізання, а не синтаксична помилка. У такому разі нічого не виправляйте — дістаньте повні дані.

3. Дві хибні тривоги з китайським текстом і екрануванням

Китайський текст перетворюється на \u4e2d\u6587: це валідне екранування JSON, а не «кракозябри». Після розбору значення відновлюється в китайський текст; форма \u показується лише тоді, коли ви дивитеся на сирий рядок безпосередньо. Коли треба показати його людям, просто виведіть його через інструмент форматування; про стратегію екранування варто дбати лише тоді, коли китайський текст має пережити URL або лог.

Китайський текст перетворюється на «кракозябри» на кшталт 涓枃: це проблема кодування, а не JSON. Вона виникає, коли байти UTF-8 декодуються як GBK, утворюючи закономірність «три символи замість одного китайського». Перевірте заголовок відповіді Content-Type: application/json; charset=utf-8 і те, чи явно вказано encoding='utf-8' під час читання файлу.

4. П'ятихвилинний робочий процес виправлення

  1. Вставте в інструмент: спершу скористайтеся онлайн-парсером, щоб знайти першу помилку, і виправляйте лише одну за раз;
  2. Перевіряйте після кожного виправлення: повторно розбирайте після кожної зміни, щоб виправлення кількох місць одразу не дало новим помилкам замаскувати стару;
  3. Один раз мініфікуйте: приберіть пробільні символи через Мініфікацію і розберіть знову; це відрізняє «структурні помилки» від «проблем із пробільними символами чи переведеннями рядка»;
  4. Порівняйте структуру: якщо після зміни раптом з'явилася помилка, скористайтеся JSON diff проти попередньої версії; різниця зазвичай — одна кома;
  5. Перевірка на рівні полів: якщо синтаксис проходить, а бізнес-рівень відхиляє (відсутнє поле, неправильний тип), це належить до перевірки JSON Schema, а не до синтаксису.

5. Чому один із двох «однакових» фрагментів JSON розбирається, а інший — ні

Найчастіша причина — невидимі символи: повноширинна кома ,, повноширинні лапки “”, нерозривний пробіл U+00A0, пробіл нульової ширини U+200B. На екрані вони майже не відрізняються від напівширинних відповідників, але жоден із них не входить до граматики JSON.

Є лише один спосіб це визначити: копіюйте вміст довкола проблемного символу й перегляньте кодові точки байт за байтом. Запуск наведеного нижче в консолі браузера перелічить кожен символ, що не є ASCII і лежить поза китайськими діапазонами:

[...text].filter((ch) => {
  const code = ch.codePointAt(0);
  return code > 127 && !(code >= 0x4e00 && code <= 0x9fff);
});

Якщо у виводі з'явиться 0x201c (ліва подвійна лапка), 0xff0c (повноширинна кома) або 0x00a0, саме вони й винні.

6. Профілактика дешевша за виправлення

  • Запускайте перевірку розбору конфігураційних файлів перед комітом; у CI достатньо одного рядка: node -e "JSON.parse(require('fs').readFileSync('config.json','utf8'))";
  • Генеруйте відповіді API бібліотекою серіалізації; ніколи не склеюйте рядки вручну — ручне склеювання є єдиним джерелом висячих ком і пропущених лапок;
  • Логуючи JSON, спершу викличте JSON.stringify, а не вставляйте його в шаблон, щоб незавершене тіло не сприйняли за повне повідомлення.

Часті питання

Як швидко знайти позицію синтаксичної помилки JSON?

Візьміть позицію або рядок/стовпець, які вказав парсер; position — це відступ символу від нуля, а не номер рядка, тоді як Java Jackson і Python одразу дають рядок і стовпець. Вставте JSON у онлайн-парсер JSON, і інструмент поставить курсор на місце помилки та підсвітить рядок і стовпець. Якщо помилка на самому початку, перевірте заголовок файлу на BOM і пошукайте невидимі символи.

Чому конфігурація, копійована з коду, так часто містить висячу кому?

Специфікація JSON забороняє висячі коми, а об'єктні літерали JavaScript їх дозволяють, тож конфігурація, копійована з JS-коду, легко тягне її за собою. Виправлення просте — видалити останню кому; якщо дані все одно належать JS-файлу, перехід на конвертацію в JSON5 підходить краще, ніж вганяти їх у JSON.

Чи можна розібрати файл конфігурації з коментарями як звичайний JSON?

Ні — у граматиці RFC 8259 немає місця для коментарів, тож прямий розбір дасть помилку. Або видаліть коментарі, або збережіть як .jsonc / .json5 і використовуйте парсер із підтримкою коментарів. Про компроміси між схемами коментарів дивіться Як писати коментарі в JSON.