Как в 1С записать JSON без лишних символов экранирования и переносов строк

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

При интеграции 1С с внешними сервисами разработчики часто сталкиваются с тем, что результирующая JSON-строка содержит «лишние» символы: \r\n (переносы строк) и обратные слэши \" перед кавычками. Это происходит из-за того, что платформа 1С при сериализации строки, содержащей JSON, обязана заэкранировать её согласно стандартам, чтобы парсер на другой стороне воспринял это именно как единое текстовое поле, а не как часть структуры. В этой статье мы разберем, как управлять этим процессом и формировать запросы правильно.

Причина появления лишних символов

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

Способ 1: Правильная иерархия объектов (Сериализация дерева)

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

Рассмотрим пример построения вложенного запроса:


// Сначала формируем внутреннюю структуру данных
ЗаказыМассив = Новый Массив;

СтруктураЗаказа = Новый Структура;
СтруктураЗаказа.Вставить("product_order", "55555");
СтруктураЗаказа.Вставить("contact", "Иванов");
СтруктураЗаказа.Вставить("tel", "0502224455");
ЗаказыМассив.Добавить(СтруктураЗаказа);

// Формируем основную структуру запроса
ЗапросОбъект = Новый Структура;
ЗапросОбъект.Вставить("client", "49");
ЗапросОбъект.Вставить("object", "order");
ЗапросОбъект.Вставить("method", "create");
ЗапросОбъект.Вставить("parameters", Новый Структура("orders", ЗаказыМассив));

// Теперь помещаем всё в корневой объект, если это требуется (например, поле "request")
КорневаяСтруктура = Новый Структура("request", ЗапросОбъект);

// Записываем в JSON за один проход
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, КорневаяСтруктура);
Результат = ЗаписьJSON.Закрыть();

При таком подходе поле request в итоговом JSON будет объектом, а не строкой, и никаких символов экранирования не появится.

Способ 2: Использование параметров записи JSON

Иногда API требует, чтобы в поле request передавался именно текст (строка в формате JSON), а не объект. В этом случае нам нужно минимизировать количество спецсимволов. Для этого в платформе 1С предусмотрен объект ПараметрыЗаписиJSON. С его помощью можно отключить переносы строк и настроить экранирование.

Разберем по шагам, как это реализовать:

  1. Создаем параметры записи, где указываем ПереносСтрокJSON.Нет.
  2. Сериализуем внутренние данные в «плоскую» строку.
  3. Вставляем полученную строку в основную структуру.

// 1. Формируем внутренний JSON без переносов
ЗаписьJSON_Внутр = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, , Ложь, ЭкранированиеСимволовJSON.Нет);
ЗаписьJSON_Внутр.УстановитьСтроку(ПараметрыЗаписи);

ВнутренняяСтруктура = Новый Структура("client, method", "49", "create");
ЗаписатьJSON(ЗаписьJSON_Внутр, ВнутренняяСтруктура);
СтрокаДляПоля = ЗаписьJSON_Внутр.Закрыть();

// 2. Формируем финальный пакет
ЗаписьJSON_Фин = Новый ЗаписьJSON;
ЗаписьJSON_Фин.УстановитьСтроку();

ГлавнаяСтруктура = Новый Структура;
ГлавнаяСтруктура.Вставить("request", СтрокаДляПоля);
ГлавнаяСтруктура.Вставить("sign", "md5_hash_string");

ЗаписатьJSON(ЗаписьJSON_Фин, ГлавнаяСтруктура);
ИтоговыйJSON = ЗаписьJSON_Фин.Закрыть();

В этом примере обратные слэши перед внутренними кавычками всё равно останутся, так как это требование стандарта JSON для строк. Однако \r\n исчезнут, что сделает строку короче и пригодной для многих сервисов.

Способ 3: Метод ЗаписатьБезОбработки()

Если вам нужно «обмануть» систему и вставить кусок текста в JSON-документ абсолютно без изменений (не добавляя кавычки по краям и не экранируя содержимое), используйте метод ЗаписатьБезОбработки(). Этот метод позволяет записывать произвольный текст напрямую в поток JSON.

Посмотрим на пример совмещения стандартной записи и ручной вставки:


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("request");

// Вставляем готовую JSON-строку как есть, без экранирования кавычек
ВнутреннийJSON = "{""client"":""49"",""object"":""order""}"; 
ЗаписьJSON.ЗаписатьБезОбработки(ВнутреннийJSON);

ЗаписьJSON.ЗаписатьИмяСвойства("status");
ЗаписьJSON.ЗаписатьЗначение("success");
ЗаписьJSON.ЗаписатьКонецОбъекта();

Результат = ЗаписьJSON.Закрыть();

Внимание: При использовании ЗаписатьБезОбработки() вы берете на себя ответственность за валидность итогового файла. Если вы вставите строку, которая не является корректным JSON-значением, сторонний сервис не сможет прочитать ваш файл. Для диагностики ошибок и исправления структуры строки можно воспользоваться инструментом для восстановления повреждённого JSON.

Особенности работы с подписями (Sign) и MD5

Часто лишние символы становятся критической проблемой при расчете контрольной суммы (хеша) запроса. Если вы считаете MD5 от «чистой» структуры 1С, а затем отправляете JSON, который платформа дозаполнила слэшами, принимающая сторона получит несовпадение подписи.

Выясним причину ошибки: алгоритм формирования подписи обычно требует «чистую» строку. Поэтому проанализируем последовательность действий:

  1. Сначала сформируйте строку для передачи (без переносов строк, используя ПараметрыЗаписиJSON).
  2. Вычислите хеш от этой конкретной строки.
  3. Добавьте хеш в итоговый объект.
  4. При финальной отправке убедитесь, что структура тела запроса (например, multipart/form-data) соответствует ожиданиям API. Если сервис ждет параметры в теле POST-запроса, возможно, вам вообще не нужно использовать ЗаписатьJSON для внешнего контейнера, а достаточно сформировать строку вида "request=" + ТекстJSON + "&sign=" + Хеш и передать её через УстановитьТелоИзСтроки().

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

← На главную