Как правильно отправить RAW data (JSON) в теле HTTP-запроса из 1С?

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

При интеграции 1С со сторонними сервисами (REST API) программисты часто сталкиваются с задачей: необходимо отправить структуру данных в формате RAW JSON в теле POST-запроса. Бывает так, что в сторонних инструментах, таких как Postman, запрос отрабатывает корректно, а из 1С сервер возвращает ошибку (например, 400 Bad Request: operation not specified). Рассмотрим подробнее, почему так происходит и как правильно формировать и отправлять такие запросы.

Разберем главную ошибку: формирование JSON-строки

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


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();            
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, ДанныеPOST, НазначениеТипаXML.Явное);
РезультатСтрока = ЗаписьJSON.Закрыть();

Проанализируем ситуацию: СериализаторXDTO предназначен для обмена данными между базами 1С. При сериализации он добавляет в итоговую строку служебные метаданные типов (например, "#type": "jcfg:Structure"). Внешние системы не понимают эти специфичные дополнения и отклоняют запрос, так как получают невалидный, с их точки зрения, JSON.

Решение: Для формирования классического, чистого JSON стандарта RFC 4627 без "мусора" всегда используйте глобальный метод ЗаписатьJSON(). Перепишем этот фрагмент:


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

Проанализируем работу с заголовками и Content-Length

В попытках передать RAW data разработчики часто пытаются вручную рассчитать размер передаваемых данных и указать заголовок Content-Length. Для этого иногда даже создают временные файлы. Это лишняя работа и антипаттерн в 1С. Посмотрим на пример кода, который лучше не использовать:


// Лишний код: ручной расчет длины
ФайлОтправки = Новый Файл(ИмяФайлаОтправки); 
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер()); 
ЗаголовкиHTTP.Вставить("Content-Length", РазмерФайлаОтправки);

Платформа 1С самостоятельно и абсолютно точно рассчитывает и подставляет заголовок Content-Length в байтах при вызове методов отправки HTTP-запроса. Если вы посчитаете длину строки программно (в символах, а не в байтах), и там окажутся кириллические символы, ваш Content-Length не совпадет с реальностью, и сервер выдаст ошибку.

Устраним невидимую угрозу: кодировка и маркер BOM

Передавая тело запроса из строки, необходимо правильно указать кодировку. Часто разработчики пишут так:


HTTPЗапрос.УстановитьТелоИзСтроки(РезультатСтрока, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.Использовать);

Большинство современных REST API строго ожидают кодировку UTF-8 без спецификации (BOM). Включение BOM добавляет в начало потока три невидимых байта. Из-за этого парсер на стороне сервера может "сломаться" и не распознать структуру JSON. Всегда используйте ИспользованиеByteOrderMark.НеИспользовать.

Рассмотрим правильный выбор типов данных: Структура или Соответствие

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

Выясним, что делать, если внешнее API требует передать ключ вида "1st-param" или "my key". В этом случае вместо структуры необходимо использовать тип Соответствие. Метод ЗаписатьJSON() обработает его аналогично структуре, сформировав правильный JSON-объект с любыми строковыми ключами.

Разберем отправку запроса и чтение ответа с ошибкой

Для отправки POST-запросов используется метод соединения ОтправитьДляОбработки(). Однако, если документация стороннего сервиса требует отправки RAW data методами PUT, PATCH или DELETE, используйте универсальный метод:

РезультатЗапроса = Соединение.ВызватьHTTPМетод("PUT", HTTPЗапрос);

Если сервер возвращает ошибку (например, статус 400) и передает пояснение в формате JSON, получить этот текст для анализа можно так:

СтрокаОтвета = РезультатЗапроса.ПолучитьТелоКакСтроку();

Посмотрим на итоговый рабочий код

Соберем все рекомендации вместе и сформируем правильный алгоритм отправки RAW JSON:


АдресРесурса = "/api/endpoint";
Соединение = Новый HTTPСоединение("api.example.com", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL());    

ЗаголовкиHTTP = Новый Соответствие;        
ЗаголовкиHTTP.Вставить("Content-Type", "application/json");
ЗаголовкиHTTP.Вставить("Accept", "application/json");
ЗаголовкиHTTP.Вставить("Authorization", "Bearer " + Токен);
// Content-Length 1С добавит автоматически

HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовкиHTTP);

// Формируем данные
ДанныеPOST = Новый Структура;
ДанныеPOST.Вставить("param1", "0");
ДанныеPOST.Вставить("param2", Истина);
ДанныеPOST.Вставить("param3", "A");

ДанныеТовары = Новый Структура;
ДанныеТовары.Вставить("param1_1", 0);
ДанныеТовары.Вставить("param1_2", "t");

М = Новый Массив;
М.Добавить(ДанныеТовары);
ДанныеPOST.Вставить("params", М);    

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

// Передаем строку в тело без BOM
HTTPЗапрос.УстановитьТелоИзСтроки(РезультатСтрока, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

// Отправляем POST запрос
РезультатЗапроса = Соединение.ОтправитьДляОбработки(HTTPЗапрос);

// Читаем ответ
КодСостояния = РезультатЗапроса.КодСостояния;
СтрокаОтвета = РезультатЗапроса.ПолучитьТелоКакСтроку();

Если КодСостояния = 200 Тогда
    Сообщить("Успешно!");
Иначе
    Сообщить("Ошибка: " + СтрокаОтвета);
КонецЕсли;

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

← На главную