DevToys Pro

бесплатные веб-инструменты для разработчиков

Блог
Оцените нас:
Попробуйте расширение для браузера:
← Назад к блогу

Завершающие запятые и комментарии в JSON: Почему ваш JSON не парсится

10 мин чтения

Вы копируете JSON конфигурацию из документации, вставляете её в приложение и получаете Unexpected token или SyntaxError. Виновник? Завершающая запятая после последнего элемента массива или полезный // комментарий, который строгие JSON парсеры отклоняют. Это руководство объясняет, почему JSON такой строгий, где появляется нестандартный JSON и как с ним работать.

Спецификация JSON: Строгость по дизайну

JSON (JavaScript Object Notation) определён RFC 8259. Он намеренно минималистичен со строгими правилами:

  • Нет завершающих запятых: Запятые разделяют элементы; завершающая запятая подразумевает отсутствующий элемент
  • Нет комментариев: JSON не имеет синтаксиса комментариев (//, /* */ или #)
  • Только двойные кавычки: Строки должны использовать ", а не '
  • Нет ключей без кавычек: Ключи объектов должны быть строками в кавычках

Почему так строго? Простота и совместимость. JSON парсеры должны производить идентичные результаты на всех языках и платформах. Допущение гибкости (как в JavaScript) нарушило бы эту гарантию.

Проблема #1: Завершающие запятые

Невалидный JSON с завершающей запятой

{
  "name": "Alice",
  "age": 30,
  "active": true,
}

Ошибка: Unexpected token } in JSON at position 53

Почему это не работает: Запятая после "active": true сигнализирует, что должно следовать ещё одно свойство. Когда парсер встречает }, он ожидает ключ, а не закрывающую скобку.

Массив с завершающей запятой

{
  "tags": ["dev", "api", "json",]
}

Ошибка: Unexpected token ] in JSON at position 36

Исправление: Удалите завершающую запятую:

{
  "name": "Alice",
  "age": 30,
  "active": true
}

{
  "tags": ["dev", "api", "json"]
}

Почему завершающие запятые так распространены

JavaScript допускает завершающие запятые (начиная с ES5):

const user = {
  name: "Alice",
  age: 30,
  active: true,  // Валидный JavaScript
};

const tags = ["dev", "api", "json",];  // Валидный JavaScript

Завершающие запятые делают диффы чище при добавлении свойств (не нужно модифицировать предыдущую строку). Разработчики, привыкшие к JavaScript, часто добавляют их в JSON, не осознавая, что JSON их не допускает.

Проблема #2: Комментарии в JSON

Невалидный JSON с комментариями

{
  // Конфигурация пользователя
  "name": "Alice",
  "age": 30,  // Обновлено 2026-01-20
  "active": true
}

Ошибка: Unexpected token / in JSON at position 4

Почему это не работает: JSON не имеет синтаксиса комментариев. Символы // не распознаются, вызывая ошибки парсинга.

Блочные комментарии также не работают

{
  /* Профиль пользователя */
  "name": "Alice",
  "age": 30
}

Ошибка: Unexpected token / in JSON at position 4

Исправление: Удалите все комментарии:

{
  "name": "Alice",
  "age": 30,
  "active": true
}

Почему комментарии появляются в JSON

  1. Примеры из документации: Туториалы часто добавляют комментарии для ясности
  2. Конфигурационные файлы: Разработчики хотят документировать настройки
  3. Влияние JavaScript: Синтаксис JSON основан на JavaScript, который допускает комментарии

Проблема #3: Одинарные кавычки

Невалидный JSON с одинарными кавычками

{
  'name': 'Alice',
  'age': 30
}

Ошибка: Unexpected token ' in JSON at position 4

Почему это не работает: JSON требует двойные кавычки (") для строк. Одинарные кавычки (') не валидны.

Исправление: Используйте двойные кавычки:

{
  "name": "Alice",
  "age": 30
}

Проблема #4: Ключи без кавычек

Невалидный JSON с ключами без кавычек

{
  name: "Alice",
  age: 30
}

Ошибка: Unexpected token n in JSON at position 4

Почему это не работает: JSON требует, чтобы ключи объектов были строками в кавычках.

Исправление: Заключите все ключи в кавычки:

{
  "name": "Alice",
  "age": 30
}

Где появляется нестандартный JSON

1. Конфигурационные файлы (JSON5, JSONC)

Многие инструменты поддерживают JSON5 или JSONC (JSON с комментариями) для конфигурационных файлов:

tsconfig.json
// JSONC - VS Code поддерживает это
{
  // Опции компилятора
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
  },
  "include": ["src/**/*"],
}

Инструменты, поддерживающие JSONC/JSON5:

  • VS Code конфигурационные файлы (settings.json, tsconfig.json)
  • Babel конфигурация (.babelrc)
  • ESLint конфигурация (.eslintrc)
  • Package.json (некоторые поля принимают комментарии через специальные ключи)

Проблема: Копирование JSONC в строгий JSON контекст (API, база данных) вызывает ошибки парсинга.

2. Примеры из документации API

Документация часто включает комментарии для ясности:

// Пример API запроса (из документации)
POST /api/users
{
  "name": "Alice",
  "email": "alice@example.com",  // Должен быть уникальным
  "role": "admin"  // Варианты: admin, user, guest
}

// Это работает в документации, но не работает в реальном API вызове!

Исправление: Удалите комментарии перед отправкой:

{
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin"
}

3. JavaScript объектные литералы

Разработчики иногда путают JavaScript объектные литералы с JSON:

// Валидный JavaScript (НЕ JSON)
const config = {
  name: "Alice",  // Ключ без кавычек
  tags: ["dev", "api",],  // Завершающая запятая
  active: true,
};

// Если вы JSON.stringify() это, получается валидный JSON:
JSON.stringify(config);
// Вывод: {"name":"Alice","tags":["dev","api"],"active":true}

Как идентифицировать и исправить нестандартный JSON

Используйте JSON валидатор

JSON форматтер и JSON валидатор немедленно выделяют синтаксические ошибки:

// Ввод с ошибками
{
  "name": "Alice",
  "age": 30,  // Комментарий
  "tags": ["dev",]  // Завершающая запятая
}

// Вывод валидатора:
// Строка 3: Unexpected token / (комментарии не допускаются)
// Строка 4: Unexpected token ] (завершающая запятая)

Удаление комментариев программно

Используйте библиотеки типа strip-json-comments (Node.js):

const stripJsonComments = require('strip-json-comments');

const jsonWithComments = `{
  // Конфигурация пользователя
  "name": "Alice",
  "age": 30  // Обновлено
}`;

const cleanJson = stripJsonComments(jsonWithComments);
const parsed = JSON.parse(cleanJson);
// Работает!

Поиск завершающих запятых с регулярным выражением

Ищите запятые, за которыми следуют закрывающие скобки:

// Паттерн регулярного выражения для поиска завершающих запятых
/,\s*([\]}])/

// Совпадает:
"tags": ["dev",]   // ← Завершающая запятая перед ]
"age": 30,}        // ← Завершающая запятая перед }

Используйте RegEx тестер, чтобы протестировать этот паттерн на вашем JSON.

JSON5: Официальный "расслабленный JSON"

JSON5 — это надмножество JSON, которое допускает распространённый синтаксис JavaScript:

// Валидный JSON5
{
  // Комментарии допускаются
  name: 'Alice',           // Ключи без кавычек, одинарные кавычки
  age: 30,
  tags: ['dev', 'api',],   // Завершающие запятые
  hexValue: 0xFF,          // Шестнадцатеричные числа
  longString: 'Это \
    многострочная строка',
}

Когда использовать JSON5:

  • Конфигурационные файлы, где люди редактируют JSON
  • Когда вы контролируете и писатель, и читатель (никаких внешних API)
  • Инструменты сборки, поддерживающие JSON5 (Babel, ESLint и т.д.)

Когда НЕ использовать JSON5:

  • API (большинство API клиентов ожидают строгий JSON)
  • Базы данных (JSON колонки ожидают RFC 8259 JSON)
  • При обмене данными с внешними системами

Распространённые сообщения об ошибках парсинга

JavaScript (Node.js, браузер)

// Завершающая запятая
SyntaxError: Unexpected token } in JSON at position 53

// Комментарий
SyntaxError: Unexpected token / in JSON at position 4

// Одинарные кавычки
SyntaxError: Unexpected token ' in JSON at position 4

// Ключи без кавычек
SyntaxError: Unexpected token n in JSON at position 4

Python

import json

# Завершающая запятая
json.loads('{"name": "Alice",}')
# json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes

# Комментарий
json.loads('{"name": "Alice" // comment}')
# json.decoder.JSONDecodeError: Expecting ',' delimiter

Go

// Завершающая запятая
err := json.Unmarshal([]byte(`{"name":"Alice",}`), &data)
// invalid character '}' looking for beginning of object key string

// Комментарий
err := json.Unmarshal([]byte(`{"name":"Alice" // comment}`), &data)
// invalid character '/' looking for beginning of value

Лучшие практики для JSON

  1. Валидируйте перед отправкой: Используйте JSON форматтер, чтобы поймать синтаксические ошибки рано
  2. Используйте JSON5 только для конфигурационных файлов: Не отправляйте JSON5 внешним API
  3. Удаляйте комментарии: Удаляйте комментарии перед парсингом строгого JSON
  4. Автоматизируйте форматирование: Используйте инструменты (Prettier, ESLint) для принудительного единообразного стиля JSON
  5. Документируйте с метаданными: Вместо комментариев в JSON используйте внешнюю документацию или ключ "_comment"

Использование ключей метаданных вместо комментариев

{
  "_comment": "Конфигурация пользователя - обновлено 2026-01-20",
  "name": "Alice",
  "age": 30,
  "active": true
}

Парсер игнорирует "_comment", но люди могут его прочитать.

Инструменты для работы с JSON

Резюме

  • JSON строгий: Нет завершающих запятых, нет комментариев, только двойные кавычки, ключи в кавычках
  • JSONC/JSON5 добавляют функции: Комментарии, завершающие запятые, ключи без кавычек—но работают только в специфичных инструментах
  • Распространённые источники нестандартного JSON: Примеры из документации, конфигурационные файлы, путаница с JavaScript
  • Исправление ошибок: Используйте валидаторы, удаляйте комментарии, убирайте завершающие запятые
  • Лучшая практика: Используйте строгий JSON для API и обмена данными; используйте JSON5 для конфигурационных файлов, редактируемых людьми

Валидируйте ваш JSON с помощью JSON форматтера, чтобы поймать завершающие запятые, комментарии и синтаксические ошибки до того, как они вызовут проблемы во время выполнения.