Форматирование и проверка JSON

Форматируйте, проверяйте и разбирайте JSON — с ошибкой, указывающей на конкретный символ.

Вывод
{
  "name": "jaguar",
  "speed_kph": 80,
  "habitats": [
    "rainforest",
    "wetland"
  ],
  "conservation": {
    "status": "Near Threatened",
    "assessed": 2016
  },
  "nocturnal": null
}

Корректный JSON

Размер
145 B
Без пробелов
145 B
Сэкономлено
0%
Ключей
7
Объектов
2
Максимальная глубина
3

Четыре ошибки

Почти каждый отвергнутый документ спотыкается об одну и ту же горстку причин, и все четыре — то, что JavaScript принял бы. В этом и ловушка: JSON выглядит как объектный литерал JavaScript, а является гораздо более строгим его подмножеством.

НаписаноПроблемаПравильно
{"a": 1,}Лишняя запятая{"a": 1}
{'a': 1}Одинарные кавычки{"a": 1}
{a: 1}Ключ без кавычек{"a": 1}
{"a": 1} // noteКомментарийУдалите его

Ещё две, на которых попадаются реже, но заметить их труднее. NaN, Infinity и undefined — допустимые значения JavaScript, и ни одно из них не является значением JSON; заменой служит null или строка. И буквальный перевод строки внутри строкового значения недопустим: там должны стоять два символа \n.

Как этот валидатор сообщает об ошибках

Об этом стоит рассказать, потому что именно ради этого выбирают один форматтер вместо другого. Для успешного пути используется браузерный JSON.parse, но не для описания сбоев: формат его сообщений — деталь реализации, менявшаяся в недавних выпусках V8 дважды. Один и тот же испорченный документ даёт «Unexpected end of JSON input» на одной версии Node и «Expected ‘,’ or ‘}’ after property value at position 6» на другой, а иногда не сообщает позицию вовсе.

Поэтому при неудачном разборе страница сама проходит по грамматике и сообщает строку, столбец и символ, на котором остановилась, с указателем снизу. Сообщение, которое вы получите, не зависит от того, каким браузером вы пользуетесь.

Проблема точности, о которой никто не предупреждает

Она вызывает настоящие ошибки и почти никогда не упоминается. Числа JSON становятся числами JavaScript, а числа JavaScript — это double по IEEE 754. Целые выше 2⁵³ — примерно 9,007 квадриллиона — точно представить нельзя.

Девятнадцатизначный идентификатор того рода, что порождают Twitter, Discord и большинство схем в духе Snowflake, вернётся изменённым, молча, без единой ошибки. Вставьте {"id": 9007199254740993} в форматтер выше и посмотрите, как сдвинется последняя цифра.

Чинить это надо на стороне отправителя: передавайте 64-битные идентификаторы строками. Все API, которых это укусило, так теперь и делают.

Когда нужен другой инструмент

Эта страница — чтобы прочитать и починить документ, который у вас перед глазами. Для двух соседних задач она не подходит:

  • Запросы и преобразования. Это jq в командной строке, который к тому же читает потоком, а не грузит всё в память, — правильный ответ для всего тяжелее пары мегабайт.
  • Проверка формы. Это JSON Schema, и проверять структуру — вопрос, отличный от проверки синтаксиса. Документ может быть безупречно оформлен и при этом не содержать ни одного поля, которого требует ваш API.

Смежное

Если JSON пришёл закодированным в Base64, сначала раскодируйте его. Если он приехал внутри токена, декодер JWT разделит и разберёт оба сегмента за вас. А если ему предстоит попасть в URL, кодировщик URL покажет, какое из трёх правил экранирования вам нужно.

Вопросы про JSON

Почему мой JSON не проходит проверку, хотя выглядит правильно?

Почти всё сводится к четырём причинам. Лишняя запятая перед закрывающей скобкой: JavaScript её принимает, JSON — нет. Одинарные кавычки вместо двойных. Комментарии, для которых в JSON вообще нет синтаксиса. И ключи без кавычек: {name: "x"} — корректный JavaScript и некорректный JSON. Валидатор выше называет, что именно из этого он нашёл, вместо того чтобы пересказывать ошибку парсера.

Безопасно ли вставлять сюда боевые данные?

В эту страницу — да: разбор идёт в вашем браузере, и нет запроса, который мог бы их унести. Убедиться можно, наблюдая за вкладкой сети во время ввода. Но привычку стоит сохранять в целом: отлаживают обычно настоящий ответ API с настоящими записями клиентов, а немало онлайн-форматтеров отправляют его на сервер, чтобы там обработать. Проверяйте перед вставкой — в любом инструменте.

Бывают ли в JSON комментарии?

Нет. Дуглас Крокфорд убрал их намеренно, потому что в них начали помещать директивы для парсеров. Если комментарии нужны в файле конфигурации, обычные ответы — JSON5 или JSONC (его использует VS Code) либо соглашение: ключ "_comment", который потребители игнорируют. Ни то, ни другое не является JSON, поэтому строгий парсер всё равно их отвергнет.

Что делает «сортировка ключей» и зачем она мне?

Она рекурсивно переставляет ключи каждого объекта по алфавиту. По спецификации объекты JSON неупорядочены, поэтому два документа, отличающиеся только порядком ключей, эквивалентны, — но текстовый diff покажет изменённой каждую строку. Отсортировав оба перед сравнением, вы сведёте всё к различиям, которые действительно важны.

Есть ли ограничение на размер?

Только ограничение вашего браузера. Разбор идёт прямо на странице, так что несколько мегабайт на настольном компьютере не проблема, а вот телефону постарше придётся потрудиться. Очень большие документы удобнее обрабатывать через jq в командной строке: он читает потоком, а не держит всё дерево в памяти.

Почему моё большое целое возвращается неверным?

Потому что числа JSON становятся числами JavaScript, то есть double по IEEE 754, а те теряют точность выше 2⁵³ — примерно 9,007 квадриллиона. Девятнадцатизначный идентификатор в духе твиттера или bigint из базы вернётся незаметно изменённым. Это не ошибка форматтера; именно поэтому API, работающие с 64-битными идентификаторами, передают их строками.

Последняя проверка . Заметили, что что-то устарело? Напишите нам.