Как передать массив данных в POST-запросе из 1С 8.2 без использования JSON?

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

При интеграции 1С с веб-сервисами программисты часто сталкиваются с требованием передать данные не в современном формате JSON или XML, а в виде "ассоциативного массива". Чаще всего такие требования выдвигают серверы, написанные на языке PHP, где данные, переданные определенным образом в теле POST-запроса, автоматически преобразуются в глобальный массив $_POST. В этой статье мы подробно разберем, как реализовать такую передачу в 1С 8.2, учитывая все технические нюансы кодирования и форматирования данных.

Понимание сути "ассоциативного массива" в HTTP-запросах

Прежде всего, проанализируем ситуацию: в протоколе HTTP не существует понятия "массив" как программного типа данных. Любой POST-запрос передает либо текстовую строку, либо двоичные данные. Когда техническая поддержка сервера говорит о "передаче ассоциативного массива", она имеет в виду стандарт application/x-www-form-urlencoded. Это тот самый формат, в котором данные отправляются из обычных HTML-форм в браузере.

Рассмотрим структуру такой строки. Она состоит из пар "ключ=значение", разделенных символом амперсанда &. Например: tovar=Шины&price=1500&quantity=4. На стороне сервера PHP увидит это как массив, где ключами будут tovar, price и quantity.

Шаг 1: Подготовка данных и URL-кодирование

Выясним причину, по которой простая конкатенация строк в 1С может привести к ошибке. Если в названии товара содержится пробел, символ &, = или кириллица, сервер не сможет корректно разобрать строку. Поэтому каждый параметр должен быть обработан функцией URL-кодирования. В 1С 8.2 для этого используется встроенная функция КодироватьСтроку.

Рассмотрим пример функции для подготовки значения:


Функция ПодготовитьЗначениеДляЗапроса(Значение)
    Возврат КодироватьСтроку(Строка(Значение), СпособКодированияСтроки.URLКодирование, "UTF-8");
КонецФункции

Важно помнить, что если ваш сервер ожидает кодировку Windows-1251, в третьем параметре следует указать соответствующее значение, но современным стандартом является UTF-8.

Шаг 2: Формирование тела запроса для вложенных массивов

Если сервер ожидает сложную структуру (вложенный массив), нам необходимо использовать специальные правила именования ключей в строке запроса. Проанализируем, как это сделать:

  1. Для передачи простого списка (индексированного массива) используйте квадратные скобки: items[]=value1&items[]=value2.
  2. Для передачи вложенного ассоциативного массива используйте ключи внутри скобок: order[id]=123&order[date]=2023-01-01.
  3. Для многомерных структур: items[0][name]=Шины&items[0][price]=1500.

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


ТекстЗапроса = "tovar=" + ПодготовитьЗначениеДляЗапроса("Шины Debica") +
               "&okpd_name=" + ПодготовитьЗначениеДляЗапроса("1.19") +
               "&price=" + СтрЗаменить(Строка(1500.50), ",", "."); // Заменяем запятую на точку для цены

Шаг 3: Настройка HTTP-заголовков и отправка запроса

Чтобы сервер понял, что мы прислали именно "ассоциативный массив", а не просто текст, мы должны обязательно установить заголовок Content-Type в значение application/x-www-form-urlencoded. Рассмотрим, как собрать все части воедино с использованием объекта HTTPСоединение.


// Определяем параметры сервера
Сервер = "api.mysite.ru";
Порт = 443; // Для HTTPS

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

// Формируем тело запроса
ТелоЗапроса = "tovar=" + КодироватьСтроку("Шины Debica", СпособКодированияСтроки.URLКодирование, "UTF-8") +
              "&price=" + "1500.00" +
              "&magaz_num=" + КодироватьСтроку("22140-T738", СпособКодированияСтроки.URLКодирование, "UTF-8");

// Отправляем запрос
HTTPСоединение = Новый HTTPСоединение(Сервер, Порт,,,, Новый ЗащищенноеСоединениеOpenSSL());
HTTPЗапрос = Новый HTTPЗапрос("/v1/update", Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Попытка
    Ответ = HTTPСоединение.ОтправитьДляОбъекта(HTTPЗапрос);
    Сообщить("Код состояния: " + Ответ.КодСостояния);
    Сообщить("Ответ сервера: " + Ответ.ПолучитьТелоКакСтроку());
Исключение
    Сообщить("Ошибка связи: " + ОписаниеОшибки());
КонецПопытки;

Использование Multipart/form-data как альтернатива

В некоторых случаях (особенно при упоминании CURLOPT_POSTFIELDS в документации к PHP) сервер может ожидать формат multipart/form-data. Это происходит, если массив данных содержит файлы или очень большие объемы текста. В 1С 8.2 формирование такого запроса вручную — задача трудоемкая, так как требуется разделять параметры уникальными границами (boundary).

Рассмотрим структуру тела multipart запроса:


--Boundary12345
Content-Disposition: form-data; name="tovar"

Шины Debica
--Boundary12345
Content-Disposition: form-data; name="price"

1500
--Boundary12345--

Если обычная строка application/x-www-form-urlencoded не принимается сервером, стоит уточнить у техподдержки, не требуется ли именно multipart формат. Однако для большинства простых API-интерфейсов первый способ является приоритетным.

Использование COM-объекта WinHttp для сложных случаев

Если штатное HTTPСоединение работает некорректно (например, при специфических требованиях к TLS или авторизации), проанализируем возможность использования WinHttpRequest. Этот объект более гибко имитирует поведение браузера.


WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("POST", "https://api.mysite.ru/v1/update", Ложь);
WinHttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");

// Тело формируется точно так же, как в первом методе
ТелоЗапроса = "tovar=Test&price=100";

WinHttp.Send(ТелоЗапроса);

Если WinHttp.Status = 200 Тогда
    Сообщить(WinHttp.ResponseText);
КонецЕсли;

Важный совет: При передаче числовых данных (цены, количества) всегда принудительно преобразуйте их в строку с использованием функции Формат, чтобы избежать появления неразрывных пробелов (разделителей групп разрядов) и использовать точку в качестве десятичного разделителя. Например: Формат(Цена, "ЧДЦ=2; ЧРД=.; ЧГ=0").

Таким образом, мы выяснили, что передача "ассоциативного массива" из 1С 8.2 сводится к правильному формированию строки параметров в формате URL-encoded и установке соответствующих заголовков. Это классический метод взаимодействия программных систем, который остается актуальным и по сей день.

← На главную