В современной разработке на платформе 1С:Предприятие 8 интеграция с внешними веб-сервисами через HTTP-протокол стала стандартной задачей. Часто возникают сценарии, когда необходимо передать не просто один параметр, а целый набор данных: авторизационные данные (логин, пароль) и непосредственно полезную нагрузку, например, файл XML или JSON. Разберем подробно, как реализовать такие запросы, используя встроенные объекты платформы.
Прежде чем переходить к коду, вспомним ключевые объекты, которые мы будем использовать:
HTTPСоединение — устанавливает сессию связи с сервером (хост, порт, учетные данные).HTTPЗапрос — формирует структуру конкретного запроса (адрес ресурса, заголовки, тело).HTTPОтвет — объект, в который платформа записывает результат выполнения запроса (код состояния, тело ответа).Рассмотрим несколько сценариев реализации запроса в зависимости от требований API стороннего сервиса.
Проанализируем ситуацию, когда данные передаются в формате обычной веб-формы. В этом случае параметры объединяются в одну строку, где пары "ключ=значение" разделены символом амперсанда &. Важно помнить о кодировании спецсимволов.
Рассмотрим пример формирования такого запроса:
&// Укажем параметры соединения
Сервер = "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 Тогда
Сообщить("Авторизация успешна!");
Иначе
Сообщить("Ошибка сервера: " + Ответ.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Ошибка связи: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Выясним причину, по которой часто рекомендуют разделять данные. Многие сервисы требуют передавать авторизацию в заголовках (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Запрос);
Это самый сложный случай. Рассмотрим ситуацию, когда сервер ожидает формат multipart/form-data. В 1С нет встроенного конструктора для этого типа данных, поэтому нам придется собрать тело запроса вручную, соблюдая структуру разделителей (boundary).
Проанализируем по шагам, как это сделать:
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);
Запрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеТела);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если принимающая сторона поддерживает 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Запрос);
При реализации обмена данными важно учитывать технические нюансы работы платформы и сетевых протоколов:
XML-файлов обязательно устанавливайте таймаут в объекте HTTPСоединение (по умолчанию он может быть слишком мал для медленных сетей).КодировкаТекста.UTF8. Платформа 1С отлично работает с UTF-8, и это стандарт для веб-сервисов.ОтправитьДляОбработки в блок Попытка...Исключение, так как сетевые ошибки (отсутствие связи, DNS-проблемы) не зависят от логики вашего кода.Выбор конкретного метода зависит исключительно от спецификации API, к которому вы подключаетесь. Если есть выбор — используйте JSON или передачу авторизации в заголовках, так как это наиболее современные и простые в отладке способы.