При интеграции систем 1С с внешними API (например, Яндекс.Маркет, Честный Знак или другие маркетплейсы) разработчики часто сталкиваются с жесткими требованиями к формату передаваемых данных. Одна из наиболее распространенных проблем связана с передачей спецсимволов в кодах маркировки, таких как GS (Group Separator), который часто представляется в виде последовательности \u001d. Стандартный механизм 1С при записи JSON неукоснительно следует спецификации RFC 8259, согласно которой обратный слэш является служебным символом и должен быть заэкранирован. В итоге вместо ожидаемого \u001d в тело запроса уходит \\u001d, что приводит к ошибке проверки кода на стороне сервера. Рассмотрим, почему это происходит и как обойти это ограничение платформы.
Проанализируем ситуацию: использование объекта ПараметрыЗаписиJSON с установкой свойства ЭкранированиеСимволовJSON.Нет (или передача Ложь в соответствующие параметры конструктора) зачастую не дает нужного результата. Разберем причину этого поведения. Параметр экранирования в 1С в первую очередь управляет символами вне диапазона ASCII (например, кириллицей). Однако управляющие символы (с кодами от U+0000 до U+001F) и сам символ обратного слэша (\) платформа будет экранировать практически всегда, чтобы сформированный текст оставался валидным с точки зрения JSON-стандарта.
Многие разработчики ошибочно полагают, что если они вручную заменяют в строке символы 91 на \u001d91, то 1С поймет это как управляющий символ. На самом деле для платформы это просто набор из 6 обычных знаков: слэш, буква "u", нули и так далее. Видя слэш, сериализатор 1С добавляет к нему второй слэш для экранирования. Выясним, как мы можем на это повлиять.
Если принимающая сторона требует именно текстовое представление \u001d с одним слэшем, самым надежным способом будет постобработка уже сформированного JSON-текста. Вместо того чтобы записывать данные напрямую в поток HTTP-запроса, мы сначала получим строку, отредактируем её и только потом отправим. Посмотрим на пример реализации этого метода:
// 1. Формируем структуру данных для отправки
СтрукОтправки = Новый Структура;
СтрукОтправки.Вставить("cis", "0104660250738335215.WxjhAJaFr,g\u001d9100C0\u001d92v9yeAe3q5Z");
// 2. Записываем JSON в строку, а не напрямую в поток
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтрукОтправки);
СериализованнаяСтрока = ЗаписьJSON.Закрыть();
// 3. Убираем лишнее экранирование (заменяем двойной слэш на одинарный)
// Важно: это затронет все экранированные символы в строке
СериализованнаяСтрока = СтрЗаменить(СериализованнаяСтрока, "\\u001d", "\u001d");
// 4. Устанавливаем тело запроса из подготовленной строки
HTTPRequest.УстановитьТелоИзСтроки(СериализованнаяСтрока);
Этот метод гарантирует, что в исходящем HTTP-пакете будет именно та последовательность символов, которую ожидает внешний сервис. Однако стоит помнить, что массовая замена всех двойных слэшей может повредить данные, если в других полях JSON действительно должны присутствовать экранированные символы. Чтобы исключить риск повреждения структуры при ручном формировании пакетов для торговых площадок, применяется интеграция 1С с маркетплейсами Ozon, Wildberries, Яндекс.Маркет, которая содержит встроенные и протестированные алгоритмы обмена.
Проанализируем альтернативный подход. Иногда проблема кроется в том, как мы формируем исходную строку в 1С. Вместо того чтобы писать текст "\u001d", попробуем вставить в строку реальный символ разделителя групп с кодом 29. В некоторых случаях 1С при сериализации такого символа сама преобразует его в \u001d без двойного экранирования. Рассмотрим, как изменить код подготовки данных:
СимволGS = Символ(29); // Код разделителя групп GS
Марк = Выборка.Маркировка;
Марк = СтрЗаменить(Марк, "91", СимволGS + "91");
Марк = СтрЗаменить(Марк, "92", СимволGS + "92");
СтрукОтправки = Новый Структура;
СтрукОтправки.Вставить("cis", Марк);
Если после такой подготовки стандартная ЗаписьJSON выдает нужный результат в потоке, то это более "чистый" способ, соответствующий стандартам разработки.
Если вы работаете на современных версиях платформы (8.3.23+), мы рекомендуем использовать упрощенный метод записи JSON. Он работает быстрее и позволяет сократить объем кода, хотя логика экранирования в нем остается аналогичной системной. Разберем пример:
// Упрощенная сериализация в строку в новых версиях платформы
СериализованнаяСтрока = ЗаписатьЗначениеJSON(СтрукОтправки);
// Проводим ту же операцию замены, если это необходимо
СериализованнаяСтрока = СтрЗаменить(СериализованнаяСтрока, "\\", "\");
HTTPRequest.УстановитьТелоИзСтроки(СериализованнаяСтрока);
При работе с экранированием символов крайне важно правильно интерпретировать то, что вы видите в конфигураторе. Проанализируем типичную ошибку: отладчик 1С всегда отображает один обратный слэш как два во внутреннем представлении строк. Если вы остановились на точке останова и видите "\\u001d", это не всегда означает, что в строке действительно два слэша. Это может быть лишь визуальное отображение спецсимвола в памяти 1С.
Для того чтобы убедиться, что именно уходит на сервер, мы рекомендуем использовать сторонние инструменты анализа трафика (снифферы), такие как Fiddler или Wireshark. Только посмотрев на "сырой" (raw) HTTP-пакет, можно однозначно сказать, произошло ли двойное экранирование или нет. Для проверки отправки сырого JSON-текста без использования внешних снифферов отлично подойдет инструмент для тестирования REST API в среде 1С.
Подведем итог: если штатные средства ЗаписьJSON и ПараметрыЗаписиJSON не позволяют добиться желаемого формата (что часто бывает с "нестрогими" API), единственным рабочим вариантом остается ручная сборка или корректировка строки JSON перед передачей в объект HTTPЗапрос. Для отправки готовых запросов по кодам маркировки к системе маркировки можно использовать обработку для запроса сведений о кодах Честного Знака.