Как передать многомерный массив и вложенные структуры в HTTP POST запросе в 1С?

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

При интеграции платформы 1С с современными веб-сервисами, интернет-магазинами и сторонними API (написанными, например, на PHP, Node.js или Python) разработчики регулярно сталкиваются с задачей передачи сложных многомерных структур данных. В PHP такие данные описываются вложенными ассоциативными массивами, например: $data = ['secret' => '...', 'parcels' => ['internalID1' => [...]]].

В этой статье мы подробно разберем, как правильно сформировать подобные вложенные данные в 1С, сериализовать их в формат JSON или подготовить для передачи в виде параметров application/x-www-form-urlencoded, а также корректно отправить их на сторонний сервер с помощью встроенных объектов HTTPЗапрос и HTTPСоединение.

Способ 1. Сериализация вложенных структур в JSON (Рекомендуемый подход)

Наиболее стандартизированным и универсальным способом обмена данными между 1С и REST API является передача тела запроса в формате JSON. Чтобы передать сложную вложенную структуру из PHP в 1С, мы используем объекты Структура или Соответствие.

Рассмотрим правила выбора объекта 1С:

Рассмотрим по шагам процесс подготовки и отправки JSON-запроса:

  1. Формируем внутренние и внешние структуры данных с соблюдением типов (числа передаем как числа, булевы значения как Истина/Ложь).
  2. Используем объекты ЗаписьJSON и функцию ЗаписатьJSON() для сериализации структуры в JSON-строку.
  3. Создаем объект HTTPЗапрос, добавляем заголовок Content-Type: application/json; charset=utf-8.
  4. Помещаем сформированную строку в тело запроса через метод УстановитьТелоИзСтроки(), при этом обязательно отключаем маркер BOM.
  5. Выполняем запрос через HTTPСоединение с поддержкой защищенного соединения SSL (при необходимости).

Проанализируем практический пример кода на языке 1С:


// Step 1. Формируем вложенные данные посылки
ДанныеПосылки = Новый Структура;
ДанныеПосылки.Вставить("type", "Ie");
ДанныеПосылки.Вставить("name_surname", "Иван Иванов");
ДанныеПосылки.Вставить("city", "ESKILSTUNA");
ДанныеПосылки.Вставить("zipcode", "1234");
ДанныеПосылки.Вставить("phone", "21234567");
ДанныеПосылки.Вставить("country_id", 4); // Передаем как число, чтобы в JSON не появилось кавычек
ДанныеПосылки.Вставить("multiparcel", 1);
ДанныеПосылки.Вставить("group_uid", "572725f8-5668-49d3-a1b2-620d0a15fdc6");

// Step 2. Вкладываем посылку во внутренний массив по ключу internalID1
ВложенныйМассив = Новый Структура;
ВложенныйМассив.Вставить("internalID1", ДанныеПосылки);

// Step 3. Собираем главный объект запроса
ГлавнаяСтруктура = Новый Структура;
ГлавнаяСтруктура.Вставить("secret", "972725f8566849d3a1b26g0d0a15fdc1");
ГлавнаяСтруктура.Вставить("parcels", ВложенныйМассив);

// Step 4. Сериализуем структуру в JSON-строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ГлавнаяСтруктура);
СтрокаJSON = ЗаписьJSON.Закрыть();

// Step 5. Подготавливаем HTTP-запрос и устанавливаем заголовки
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

Запрос = Новый HTTPЗапрос("/api/v1/parcels", Заголовки);

// Очень важно: отключаем Byte Order Mark (BOM)
Запрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

// Step 6. Настраиваем защищенное соединение и отправляем данные
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("api.example.com", 443, , , , , ЗащищенноеСоединение);

Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Способ 2. Передача многомерного массива в формате application/x-www-form-urlencoded

Если веб-сервер или старый скрипт на PHP принимает данные исключительно через стандартный глобальный массив $_POST и не умеет разбирать входящее тело JSON-запроса из потока php://input, передача JSON вызовет ошибку на стороне сервера.

В этом случае вложенный массив PHP ожидается в виде кодированной строки параметров с синтаксисом квадратных скобок: parcels[internalID1][type]=Ie&parcels[internalID1][city]=ESKILSTUNA....

Разберем по шагам, как сформировать такую строку вручную с кодированием спецсимволов:


// Формируем параметры в формате синтаксиса массивов PHP
ПараметрыМассива = Новый Массив;
ПараметрыМассива.Добавить("secret=972725f8566849d3a1b26g0d0a15fdc1");
ПараметрыМассива.Добавить("parcels[internalID1][type]=" + КодироватьСимволы("Ie"));
ПараметрыМассива.Добавить("parcels[internalID1][name_surname]=" + КодироватьСимволы("Иван Иванов"));
ПараметрыМассива.Добавить("parcels[internalID1][city]=" + КодироватьСимволы("ESKILSTUNA"));
ПараметрыМассива.Добавить("parcels[internalID1][zipcode]=" + КодироватьСимволы("1234"));
ПараметрыМассива.Добавить("parcels[internalID1][phone]=" + КодироватьСимволы("21234567"));
ПараметрыМассива.Добавить("parcels[internalID1][country_id]=4");
ПараметрыМассива.Добавить("parcels[internalID1][multiparcel]=1");
ПараметрыМассива.Добавить("parcels[internalID1][group_uid]=572725f8-5668-49d3-a1b2-620d0a15fdc6");

// Соединяем параметры через амперсанд
СтрокаPOST = СтрСоединить(ПараметрыМассива, "&");

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");

Запрос = Новый HTTPЗапрос("/api/v1/parcels", Заголовки);
Запрос.УстановитьТелоИзСтроки(СтрокаPOST, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("api.example.com", 443, , , , , ЗащищенноеСоединение);

Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Обработка ответа сервера

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

Рассмотрим пример обработки ответа:


КодСостояния = Ответ.КодСостояния;

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

Типичные ошибки при передаче HTTP POST запросов и способы их исправления

При интеграции 1С с веб-сервисами часто возникают специфические проблемы. Проанализируем основные причины сбоев и методы их устранения:

  1. Символы маркера последовательности байтов (BOM):
    По умолчанию при сохранении строки в кодировке UTF-8 платформа 1С может добавлять в начало строки специальный заголовок (BOM). Некоторые парсеры JSON (включая стандартный json_decode() в PHP) из-за этого выдают ошибку синтаксиса.
    Решение: Всегда явно передавайте третий параметр ИспользованиеByteOrderMark.НеИспользовать в метод Запрос.УстановитьТелоИзСтроки().
  2. Несоответствие типов данных:
    Если веб-сервис ожидает числовое значение (например, "country_id": 4), а вы записали его в 1С как строку "4", при сериализации в JSON оно будет обернуто в кавычки. Сервер с строгой валидацией типов вернет ошибку 400 Bad Request.
    Решение: Привязывайте точные типы данных 1С (Число, Булево, Строка) при заполнении структуры.
  3. Отсутствие заголовка Content-Type:
    Если заголовок Content-Type не указан явно, принимающий веб-сервер не сможет определить формат переданных данных и проигнорирует тело запроса.
    Решение: Всегда заполняйте соответствие заголовков перед созданием HTTPЗапрос.
  4. Недопустимые символы в ключах структуры:
    Попытка добавить в объект Структура ключ с дефисом (например, Данные.Вставить("user-id", 1)) вызовет ошибку выполнения в 1С.
    Решение: В таких случаях вместо Структура используйте объект Соответствие, который поддерживает любые строковые ключи.
← На главную