developer • 7 мин чтения • Обновлено: 2026-09-17

Спецификация JSON RFC 8259 и типичные ошибки парсинга

JSON (JavaScript Object Notation) стал общепринятым стандартом обмена данными в веб-сервисах, микросервисах и REST API. Однако простота формата обманчива: в статье разбираем неочевидные тонкости стандарта RFC 8259, фатальную потерю точности 64-битных чисел в JavaScript и правила безопасной обработки полезной нагрузки.

Спецификация RFC 8259: отличия JSON от объекта JavaScript

Распространённое заблуждение новичков: считать, что любой объект JavaScript является валидным JSON. Это не так. Спецификация RFC 8259 (и стандарт ECMA-404) накладывает предельно жёсткие ограничения:

1. Кавычки ключей: В JavaScript допустимы объекты вида { name: 'Иван' }. В JSON ключи обязаны быть строками в двойных кавычках: { "name": "Иван" }. Одинарные кавычки вызывают фатальную ошибку SyntaxError.
2. Запятые: Висячие запятые (trailing commas) в конце списков { "a": 1, "b": 2, } в JSON строго запрещены.
3. Типы данных: JSON поддерживает только 6 типов: string, number, boolean, null, object, array. Такие типы, как undefined, Function, Date, RegExp, BigInt или Symbol, в стандарте отсутствуют. Значения Date при сериализации автоматически превращаются в ISO-строку.

Полезный инструмент: Для работы со сложными иерархическими структурами используйте наш онлайн-форматтер JSON и валидатор JSON синтаксиса.

Полезный инструмент: При передаче данных через заголовки API (например, в связке с Base64 кодером).

Критическая ловушка: 64-битные целые числа (BigInt / Snowflake ID)

Спецификация JSON теоретически не ограничивает длину числовых значений. Однако в JavaScript встроенный движок парсинга JSON.parse() преобразует все числа в тип Number — 64-битное число с плавающей точкой по стандарту IEEE 754.

Максимальное безопасное целое число в JS:
Number.MAX_SAFE_INTEGER = 2^53 - 1 = 9 007 199 254 740 991 (16 десятичных знаков).


Если ваш бэкенд на Go, C#, Java или PostgreSQL отдаёт 64-битные идентификаторы (BIGINT, Twitter Snowflake ID, транзакции блокчейна), например 18446744073709551615:
const data = JSON.parse('{"id": 18446744073709551615}');
console.log(data.id); // Результат: 18446744073709552000!


Два младших разряда безвозвратно искажаются из-за нехватки бит мантиссы. В результате клик по кнопке удаления отправляет запрос с искажённым ID, затрагивая чужие сущности.
Золотое правило API: любые 64-битные целые идентификаторы обязаны передаваться в JSON как строки: {"id": "18446744073709551615"}.

Циклические ссылки и кастомные реплейсеры

Попытка сериализовать объект, содержащий ссылку на самого себя или родительский узел дерева:
const user = {};

user.self = user;
JSON.stringify(user); // Выбросит TypeError: Converting circular structure to JSON

Для безопасной сериализации сложных графов объектов с циклическими связями используется функция-реплейсер (replacer) со структурой WeakSet:

function safeStringify(obj, indent = 2) {
const seen = new WeakSet();

return JSON.stringify(obj, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular Reference]';
seen.add(value);
}
return value;
}, indent);
}

Форматирование против минификации: где что применять

• При разработке, логировании и отладке в IDE используйте отступ в 2 пробела (prettify) — он обеспечивает максимальную читаемость структуры дерева при минимальном горизонтальном скролле.
• В продакшн-окружении (передача ответов микросервисов, кэш в Redis, очереди RabbitMQ/Kafka) всегда используйте минификацию (удаление пробелов и переводов строк). Это снижает объём полезной нагрузки на 20–35% и экономит трафик при миллионах RPS.

Часто задаваемые вопросы (FAQ)

Спецификация JSON допускает числа произвольной длины, однако движок JavaScript использует 64-битные числа с плавающей точкой IEEE 754 (Number.MAX_SAFE_INTEGER = 9007199254740991). При парсинге длинных 64-битных целых ID младшие биты теряются. Решение: передавать длинные идентификаторы в виде строк ("id": "1234567890123456789").

Нет. Стандарт RFC 8259 строго требует обрамления строк и названий ключей исключительно двойными кавычками ("key": "value"). Комментарии (// или /* */) и висячие запятые (trailing commas) запрещены спецификацией и вызывают фатальную ошибку SyntaxError.

Форматирование добавляет переносы строк и отступы (обычно 2 или 4 пробела) для удобства чтения человеком и локализации ошибок. Минификация удаляет все лишние пробельные символы, экономя от 15% до 40% размера полезной нагрузки при сетевой передаче через REST API.

Никогда не формируйте JSON-строки через склеивание строк вручную. Всегда сериализуйте данные через доверенные функции (json_encode в PHP или JSON.stringify в JS) и валидируйте входящую структуру по JSON Schema, отсекая непредусмотренные поля.

По спецификации RFC 8259 объект JSON представляет собой неупорядоченную коллекцию пар ключ-значение. Хотя большинство современных парсеров сохраняют порядок вставки, бизнес-логика не должна зависеть от порядка ключей. Если порядок элементов критичен, используйте массив.

Скопировано в буфер обмена!