В современной разработке на платформе 1С:Предприятие 8.3 часто возникает необходимость интеграции с внешними веб-сервисами. Одной из наиболее трудоемких задач является отправка файлов (изображений, документов, архивов) с использованием метода POST. В данной статье мы подробно разберем, как правильно сконфигурировать объекты HTTPСоединение и HTTPЗапрос, а также как сформировать тело запроса в формате multipart/form-data.
Рассмотрим ситуацию, когда нам необходимо передать файл на сервер. Стандартный механизм HTTP-протокола для передачи файлов требует особого оформления тела запроса. В 1С для этих целей используются встроенные объекты для работы с интернет-протоколами. Проанализируем основные этапы реализации этой задачи:
boundary).HTTPЗапрос.HTTPСоединение и обработка ответа.Прежде чем отправлять запрос, необходимо установить соединение с сервером. Разберем параметры, которые нам понадобятся. Мы будем использовать объект HTTPСоединение, указывая адрес сервера и параметры безопасности (SSL), если это необходимо.
// Определим параметры сервера
Сервер = "api.service.ru";
Порт = 443; // Для HTTPS
ИспользованиеSSL = Новый ЗащищенноеСоединениеOpenSSL();
// Создаем соединение
Соединение = Новый HTTPСоединение(Сервер, Порт, , , , , ИспользованиеSSL);
Важно помнить, что при работе с защищенным соединением необходимо инициализировать ЗащищенноеСоединениеOpenSSL, иначе запрос к https завершится ошибкой.
Для передачи файлов используется тип содержимого multipart/form-data. Ключевой особенностью является boundary — уникальная строка, которая отделяет разные части данных друг от друга. Выясним, как правильно сформировать заголовок запроса.
Проанализируем пример формирования заголовков:
Граница = Строка(Новый УникальныйИдентификатор());
Запрос = Новый HTTPЗапрос("/upload");
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Граница);
Использование УникальныйИдентификатор() гарантирует, что строка разделителя не встретится внутри самого файла, что предотвратит повреждение данных при парсинге на стороне сервера.
Это самый ответственный этап. Тело запроса должно строго соответствовать стандарту RFC 2388. Рассмотрим структуру каждой части. Каждая секция начинается с разделителя, за которым следуют метаданные (имя поля, имя файла), пустая строка и само содержимое.
Разберем по шагам создание тела запроса в коде 1С:
// Считываем файл в двоичные данные
ПутьКФайлу = "C:\temp\document.pdf";
ФайлДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
// Начинаем формировать текстовую часть тела
ТекстТела = "--" + Граница + Символы.ПС;
ТекстТела = ТекстТела + "Content-Disposition: form-data; name=""file""; filename=""document.pdf""" + Символы.ПС;
ТекстТела = ТекстТела + "Content-Type: application/pdf" + Символы.ПС + Символы.ПС;
// Преобразуем текст в двоичные данные (используя UTF-8)
ДвоичныеДанныеНачала = ПолучитьДвоичныеДанныеИзСтроки(ТекстТела, КодировкаТекста.UTF8, Ложь);
// Формируем завершающий разделитель
ТекстЗавершения = Символы.ПС + "--" + Граница + "--" + Символы.ПС;
ДвоичныеДанныеКонца = ПолучитьДвоичныеДанныеИзСтроки(ТекстЗавершения, КодировкаТекста.UTF8, Ложь);
// Соединяем все части в один поток
МассивЧастей = Новый Массив;
МассивЧастей.Добавить(ДвоичныеДанныеНачала);
МассивЧастей.Добавить(ФайлДвоичныеДанные);
МассивЧастей.Добавить(ДвоичныеДанныеКонца);
ПолноеТелоЗапроса = ОбъединитьДвоичныеДанные(МассивЧастей);
Запрос.УстановитьТелоИзДвоичныхДанных(ПолноеТелоЗапроса);
Обратите внимание на использование функции ОбъединитьДвоичныеДанные. Это наиболее эффективный способ сборки больших запросов, так как он минимизирует использование оперативной памяти по сравнению с конкатенацией строк или использованием ЗаписьДанных.
После того как объект HTTPЗапрос полностью укомплектован заголовками и телом, мы отправляем его на сервер. Проанализируем ситуацию получения ответа. Нам важно проверить код состояния (HTTP Status Code), чтобы убедиться в успешности операции.
Попытка
Ответ = Соединение.ОтправитьДляОбъекта(Запрос);
КодСостояния = Ответ.КодСостояния;
Если КодСостояния = 200 Тогда
Сообщить("Файл успешно отправлен!");
РезультатТекст = Ответ.ПолучитьТелоКакСтроку();
// Разбор JSON или XML ответа сервера
Иначе
Сообщить("Ошибка при отправке. Код: " + КодСостояния);
Сообщить("Ответ сервера: " + Ответ.ПолучитьТелоКакСтроку());
КонецЕсли;
Исключение
Сообщить("Произошла критическая ошибка связи: " + ОписаниеОшибки());
КонецПопытки;
Важным моментом является использование блока Попытка...Исключение. Ошибки могут возникнуть на уровне сетевого протокола (отсутствие интернета, таймаут, неверный адрес), и их необходимо корректно обрабатывать, чтобы программа не завершилась аварийно.
При реализации обмена данными стоит учитывать несколько технических нюансов, которые помогут сделать интеграцию более стабильной:
HTTPСоединение (параметр в секундах).КодировкаТекста.UTF8 при преобразовании строк в двоичные данные, так как серверы чаще всего ожидают именно эту кодировку.multipart/form-data. Некоторые API требуют передачи файла в теле напрямую (binary stream) без разделителей. В этом случае достаточно просто использовать Запрос.УстановитьТелоИзФайла(ПутьКФайлу).HTTPСоединение.Мы рассмотрели универсальный и наиболее гибкий способ отправки файлов. Данный подход позволяет передавать не только сам файл, но и дополнительные текстовые поля в одном запросе, просто добавляя новые секции между разделителями boundary.