Как отправить POST-запрос с несколькими параметрами и файлом в 1С

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

В современной разработке на платформе 1С:Предприятие 8 интеграция с внешними веб-сервисами через HTTP-протокол стала стандартной задачей. Часто возникают сценарии, когда необходимо передать не просто один параметр, а целый набор данных: авторизационные данные (логин, пароль) и непосредственно полезную нагрузку, например, файл XML или JSON. Разберем подробно, как реализовать такие запросы, используя встроенные объекты платформы.

Основные объекты для работы с HTTP

Прежде чем переходить к коду, вспомним ключевые объекты, которые мы будем использовать:

  1. HTTPСоединение — устанавливает сессию связи с сервером (хост, порт, учетные данные).
  2. HTTPЗапрос — формирует структуру конкретного запроса (адрес ресурса, заголовки, тело).
  3. HTTPОтвет — объект, в который платформа записывает результат выполнения запроса (код состояния, тело ответа).

Рассмотрим несколько сценариев реализации запроса в зависимости от требований API стороннего сервиса.

Вариант 1: Параметры в теле запроса (x-www-form-urlencoded)

Проанализируем ситуацию, когда данные передаются в формате обычной веб-формы. В этом случае параметры объединяются в одну строку, где пары "ключ=значение" разделены символом амперсанда &. Важно помнить о кодировании спецсимволов.

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


&// Укажем параметры соединения
Сервер = "api.service.com";
Соединение = Новый HTTPСоединение(Сервер, , , , , , Новый ЗащищенноеСоединениеOpenSSL());

// Формируем адрес ресурса
АдресРесурса = "/v1/auth/login";

// Создаем запрос
Запрос = Новый HTTPЗапрос(АдресРесурса);

// Устанавливаем заголовок контента
Запрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");

// Формируем тело запроса
Логин = "admin";
Пароль = "P@ssw0rd123";
ТелоЗапроса = "grant_type=password&username=" + Логин + "&password=" + Пароль;

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

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

Вариант 2: Передача данных через заголовки и тело

Выясним причину, по которой часто рекомендуют разделять данные. Многие сервисы требуют передавать авторизацию в заголовках (Headers), а полезные данные (например, XML-файл) — в теле. Это более безопасно и соответствует стандартам REST API.

Разберем пример, где логин и пароль передаются для Basic Authentication, а тело содержит XML:


// Создаем соединение с указанием логина и пароля
// Платформа сама сформирует заголовок Authorization: Basic
Соединение = Новый HTTPСоединение("api.myserver.ru", , "myLogin", "myPassword");

HTTPЗапрос = Новый HTTPЗапрос("/api/upload/data");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");

// Если XML уже сформирован в строке
ТекстXML = "<data><item>Пример</item></data>";
HTTPЗапрос.УстановитьТелоИзСтроки(ТекстXML, КодировкаТекста.UTF8);

// Если XML находится в файле на диске
// HTTPЗапрос.УстановитьТелоИзФайла("C:\temp\export.xml");

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

Вариант 3: Передача нескольких параметров и файла (Multipart/form-data)

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

Проанализируем по шагам, как это сделать:

  1. Создаем уникальный разделитель (Boundary).
  2. Формируем текстовые блоки для каждого строкового параметра.
  3. Считываем файл в двоичные данные.
  4. Собираем все части в один поток данных.

Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
ИмяФайла = "document.xml";
ПутьКФайлу = "C:\temp\document.xml";

// Начало формирования тела
МассивДанных = Новый Массив;

// Параметр "login"
ТекстПараметра = "--" + Boundary + Символы.ВК + Символы.ПС;
ТекстПараметра = ТекстПараметра + "Content-Disposition: form-data; name=""login""" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС;
ТекстПараметра = ТекстПараметра + "my_user_login" + Символы.ВК + Символы.ПС;
МассивДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(ТекстПараметра));

// Параметр "file"
ТекстФайла = "--" + Boundary + Символы.ВК + Символы.ПС;
ТекстФайла = ТекстФайла + "Content-Disposition: form-data; name=""xml_file""; filename=""" + ИмяФайла + """" + Символы.ВК + Символы.ПС;
ТекстФайла = ТекстФайла + "Content-Type: text/xml" + Символы.ВК + Символы.ПС + Символы.ВК + Символы.ПС;
МассивДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(ТекстФайла));

// Само содержимое файла
МассивДанных.Добавить(Новый ДвоичныеДанные(ПутьКФайлу));

// Финальный разделитель
МассивДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(Символы.ВК + Символы.ПС + "--" + Boundary + "--"));

// Объединяем все части
ДвоичныеДанныеТела = СоединитьДвоичныеДанные(МассивДанных);

// Настройка запроса
Запрос = Новый HTTPЗапрос("/upload");
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
Запрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеТела);

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

Вариант 4: Использование JSON и Base64

Если принимающая сторона поддерживает JSON, мы можем пойти по пути упрощения. Вместо сложной сборки multipart, мы преобразуем XML-файл в строку Base64 и отправим его как обычное текстовое поле.

Посмотрим на пример реализации:


// Читаем файл и кодируем в Base64
ДвоичныеДанныеФайла = Новый ДвоичныеДанные("C:\data\file.xml");
СтрокаBase64 = Base64Строка(ДвоичныеДанныеФайла);

// Формируем структуру JSON
ДанныеДляОтправки = Новый Структура;
ДанныеДляОтправки.Вставить("login", "admin");
ДанныеДляОтправки.Вставить("password", "12345");
ДанныеДляОтправки.Вставить("file_data", СтрокаBase64);
ДанныеДляОтправки.Вставить("file_name", "data.xml");

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

// Отправка
HTTPЗапрос = Новый HTTPЗапрос("/api/v2/receive");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json");
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8);

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

Важные рекомендации при работе с HTTP

При реализации обмена данными важно учитывать технические нюансы работы платформы и сетевых протоколов:

Выбор конкретного метода зависит исключительно от спецификации API, к которому вы подключаетесь. Если есть выбор — используйте JSON или передачу авторизации в заголовках, так как это наиболее современные и простые в отладке способы.

← На главную