Как правильно прочитать JSON в 1С и решить проблемы с кодировкой и ошибками разбора свойств

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции систем 1С со сторонними веб-сервисами через HTTP API разработчики часто сталкиваются с форматом JSON. На первый взгляд процесс кажется тривиальным, однако на практике возникают типичные проблемы: появление непонятных символов вида \u041a\u043e... вместо привычного русского текста, ошибки при попытке десериализации объектов со специфическими ключами, а также критическое падение производительности при чтении больших объемов данных.

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

Выясняем причину: почему «\u041a...» — это не ошибка кодировки

Рассмотрим ситуацию, с которой часто сталкиваются начинающие разработчики. При получении текстового ответа от веб-сайта в отладчике или через команду Сообщить() выводится следующая строка:


{"message":"","result":[{"id":"954434","title":"\u041a\u043e\u0440\u043e\u0431\u043a\u0438 \u0441\u043e \u0441\u0442\u0435\u043a\u043b\u043e\u043c"}]}

Первая реакция программиста — попытаться принудительно перекодировать строку, предполагая, что произошел сбой кодировки UTF-8. Однако это в корне неверно.

По международной спецификации формата JSON (RFC 8259), любые символы, не входящие в базовую латиницу ASCII (включая кириллицу), могут быть заэкранированы с помощью шестнадцатеричной последовательности Unicode вида \uXXXX. В нашем примере последовательность \u041a означает заглавную русскую букву «К», \u043e — строчную «о», и так далее. Строка "\u041a\u043e\u0440\u043e\u0431\u043a\u0438" — это абсолютно валидное, стандартное представление слова «Коробки».

При парсинге такого текста стандартными встроенными средствами 1С (с помощью объекта ЧтениеJSON и метода ПрочитатьJSON()) платформа автоматически декодирует эти последовательности в нормальные русские буквы. Ошибки с кодировкой UTF-8 здесь нет: путаница возникает исключительно на этапе просмотра «сырого» текста HTTP-ответа. Как только вы прочитаете JSON в объекты 1С, вы получите нормальный русский текст.

Главное заблуждение: Структура против Соответствия

Другая распространенная проблема возникает непосредственно во время вызова функции ПрочитатьJSON(), когда платформа аварийно завершает работу с ошибкой вида: «Недопустимое имя свойства... для чтения JSON в объект Структура».

Давайте проанализируем, почему это происходит. По умолчанию функция ПрочитатьJSON(ЧтениеJSON) пытается преобразовать объекты JSON в привычный для разработчиков 1С тип данных — Структура. Однако к ключам структуры в 1С предъявляются строгие требования, аналогичные правилам именования переменных (идентификаторов):

  1. Имя ключа не может начинаться с цифры.
  2. Имя ключа не может содержать пробелов, дефисов, точек и других спецсимволов.

Если в вашем JSON-документе встречается свойство с именем "954434" (как в примере автора темы) или "user-id", попытка записать его в качестве ключа структуры вызовет ошибку, так как Структура["954434"] или Структура["user-id"] существовать в 1С не могут.

Для решения этой проблемы используется второй параметр функции ПрочитатьJSON() — ИменаСвойствСоЗначениямиДата, а точнее, параметр, отвечающий за чтение объектов в Соответствие (Map) вместо Структуры. Посмотрим на синтаксис функции:


ПрочитатьJSON(<ЧтениеJSON>, <ПрочитыватьВСоответствие>, <ИменаСвойствСоЗначениямиДата>, ...)

Если во второй параметр передать значение Истина, платформа прочитает JSON-объекты в коллекцию типа Соответствие. Ключами соответствия в 1С могут выступать абсолютно любые строковые значения, включая числа, строки с пробелами и спецсимволами.

Давайте сравним эти подходы на практике:


// Этот код вызовет ошибку, если в JSON есть ключи-числа или ключи с дефисами
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(ТекстJSON);
Данные = ПрочитатьJSON(ЧтениеJSON, Ложь); // Ложь - поведение по умолчанию (Структура)
ЧтениеJSON.Закрыть();

// А этот код отработает идеально в любых условиях
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(ТекстJSON);
Данные = ПрочитатьJSON(ЧтениеJSON, Истина); // Истина - читать в Соответствие
ЧтениеJSON.Закрыть();

Таким образом, использование параметра Истина никак не связано с «исправлением кодировки», как ошибочно предполагали некоторые участники форума. Оно лишь переключает внутренний тип создаваемой коллекции со Структуры на Соответствие, снимая любые ограничения на имена ключей.

Оптимальный обход полученных данных

После того как данные успешно десериализованы в коллекцию 1С, необходимо обойти их для последующей обработки. Если результатом парсинга является массив объектов, забудьте об использовании циклов со счетчиками (таких как Для Счетчик = 0 По Массив.Количество() - 1 Цикл). Во-первых, индексация в 1С начинается с 0, что часто приводит к ошибкам «выхода за границы массива» при невнимательном написании условий. Во-вторых, такой код избыточен.

Для обхода коллекций в 1С применяется лаконичный и быстрый цикл Для каждого ... Из ... Цикл. Рассмотрим пример разбора ответа, в котором мы получили массив результатов:


// Предположим, Данные - это Соответствие, полученное из ПрочитатьJSON(ЧтениеJSON, Истина)
МассивРезультатов = Данные.Получить("result");

Если ТипЗнч(МассивРезультатов) = Тип("Массив") Тогда
    Для каждого Элемент Из МассивРезультатов Цикл
        // Каждый Элемент - это тоже Соответствие
        Идентификатор = Элемент.Получить("id");
        Заголовок     = Элемент.Получить("title");
        Описание      = Элемент.Получить("description");
        
        Сообщить("ID: " + Идентификатор + " | Название: " + Заголовок);
    КонецЦикла;
КонецЕсли;

Оптимизация памяти при работе с большими JSON (Потоковое чтение)

В коде, который часто копируют из старых обработок, можно встретить следующую конструкцию загрузки данных:


СтрокаОтвета = HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8");
ЧтениеJSON.УстановитьСтроку(СтрокаОтвета);
Данные = ПрочитатьJSON(ЧтениеJSON, Истина);

Разберем, почему этот подход опасен. Метод ПолучитьТелоКакСтроку() считывает весь HTTP-ответ в оперативную память сервера 1С в виде одной непрерывной текстовой переменной. Если размер получаемого JSON-файла составляет десятки или сотни мегабайт (например, при выгрузке большого каталога товаров), сервер 1С может исчерпать доступную память. Это приведет к значительному замедлению работы всей системы или к аварийному завершению рабочего процесса (ошибка Out of Memory).

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

Реализуется это следующим образом:


// Выполняем запрос к веб-сервису
Ответ = Соединение.ВызватьHTTPМетод(МетодЗапроса, HTTPЗапрос);

Если Ответ.КодСостояния = 200 Тогда
    ЧтениеJSON = Новый ЧтениеJSON;
    
    // Получаем тело ответа в виде потока и сразу передаем его в объект чтения
    ПотокТела = Ответ.ПолучитьТелоКакПоток();
    ЧтениеJSON.ОткрытьПоток(ПотокТела);
    
    // Выполняем десериализацию напрямую из потока в Соответствие
    ДанныеJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
    
    // Обязательно закрываем объект чтения для освобождения системных ресурсов
    ЧтениеJSON.Закрыть();
Иначе
    Сообщить("Ошибка запроса. Код ответа сервера: " + Ответ.КодСостояния);
КонецЕсли;

При таком подходе потребление оперативной памяти сервером 1С будет минимальным и стабильным, независимо от того, весит ли JSON-файл 100 килобайт или 500 мегабайт.

Автоматическое распознавание дат

Как известно, в самом формате JSON нет типа данных «Дата». Даты обычно передаются как стандартные строки (например, в формате ISO 8601: "2026-03-29T15:30:00Z"). Чтобы программисту не приходилось вручную перебирать все текстовые поля и преобразовывать их в формат даты 1С с помощью сложных строковых манипуляций, в платформе предусмотрен встроенный парсер дат.

Для автоматического преобразования строк в даты мы можем задействовать 3-й и 4-й параметры функции ПрочитатьJSON(). Мы передаем массив имен свойств, которые содержат даты, и указываем ожидаемый формат:


// Зададим список полей, которые система должна автоматически преобразовать в Дату 1С
МассивИменДаты = Новый Массив;
МассивИменДаты.Добавить("date_created");
МассивИменДаты.Добавить("date_updated");

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьПоток(Ответ.ПолучитьТелоКакПоток());

// Читаем JSON, указывая параметры автоматического парсинга дат
Данные = ПрочитатьJSON(ЧтениеJSON, Истина, МассивИменДаты, ФорматДатыJSON.ISO);
ЧтениеJSON.Закрыть();

// Теперь значения полей "date_created" и "date_updated" будут иметь тип Дата, а не Строка!
Создано = Данные.Получить("date_created"); 
Сообщить(ТипЗнч(Создано)); // Выведет: Дата

Обратная задача: управление кодированием при отправке JSON

Если вы решаете обратную задачу — формируете JSON-пакет в 1С для его последующей отправки на веб-сайт, и хотите управлять тем, как будут выглядеть русские буквы (оставлять их читаемыми или кодировать в последовательности \uXXXX), вы можете использовать объект ПараметрыЗаписиJSON.

Для этого при инициализации объекта ЗаписьJSON настраивается свойство ЭкранированиеСимволов. Посмотрим на примере:


// Настраиваем параметры записи JSON
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(,,, ЭкранированиеСимволовJSON.Нет);

ЗаписьJSON = Новый ЗаписьJSON;
// Передаем параметры записи при открытии файла или потока
ЗаписьJSON.ОткрытьФайл("C:\temp\export.json", "UTF-8", , ПараметрыЗаписи);

ДанныеДляОтправки = Новый Структура;
ДанныеДляОтправки.Вставить("title", "Коробки со стеклом");

ЗаписатьJSON(ЗаписьJSON, ДанныеДляОтправки);
ЗаписьJSON.Закрыть();

Использование значения ЭкранированиеСимволовJSON.Нет гарантирует, что в результирующем файле русские буквы сохранятся в обычном, легко читаемом виде (например, "title":"Коробки со стеклом"), что позволит сэкономить размер отправляемого пакета данных.

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

← На главную