Как программно отправить файл через HTTP POST в 1С 8.3: подробное руководство

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

В современной разработке на платформе 1С:Предприятие 8.3 часто возникает необходимость интеграции с внешними веб-сервисами. Одной из наиболее трудоемких задач является отправка файлов (изображений, документов, архивов) с использованием метода POST. В данной статье мы подробно разберем, как правильно сконфигурировать объекты HTTPСоединение и HTTPЗапрос, а также как сформировать тело запроса в формате multipart/form-data.

Постановка задачи и выбор инструментов

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

  1. Подготовка файла и перевод его в двоичные данные.
  2. Создание уникального разделителя (boundary).
  3. Формирование текстового и бинарного состава тела запроса.
  4. Настройка заголовков HTTPЗапрос.
  5. Выполнение запроса через HTTPСоединение и обработка ответа.

Шаг 1: Подготовка объекта HTTPСоединение

Прежде чем отправлять запрос, необходимо установить соединение с сервером. Разберем параметры, которые нам понадобятся. Мы будем использовать объект HTTPСоединение, указывая адрес сервера и параметры безопасности (SSL), если это необходимо.


// Определим параметры сервера
Сервер = "api.service.ru";
Порт = 443; // Для HTTPS
ИспользованиеSSL = Новый ЗащищенноеСоединениеOpenSSL();

// Создаем соединение
Соединение = Новый HTTPСоединение(Сервер, Порт, , , , , ИспользованиеSSL);

Важно помнить, что при работе с защищенным соединением необходимо инициализировать ЗащищенноеСоединениеOpenSSL, иначе запрос к https завершится ошибкой.

Шаг 2: Формирование заголовков и разделителя

Для передачи файлов используется тип содержимого multipart/form-data. Ключевой особенностью является boundary — уникальная строка, которая отделяет разные части данных друг от друга. Выясним, как правильно сформировать заголовок запроса.

Проанализируем пример формирования заголовков:


Граница = Строка(Новый УникальныйИдентификатор());
Запрос = Новый HTTPЗапрос("/upload");
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Граница);

Использование УникальныйИдентификатор() гарантирует, что строка разделителя не встретится внутри самого файла, что предотвратит повреждение данных при парсинге на стороне сервера.

Шаг 3: Формирование тела запроса (Multipart/form-data)

Это самый ответственный этап. Тело запроса должно строго соответствовать стандарту RFC 2388. Рассмотрим структуру каждой части. Каждая секция начинается с разделителя, за которым следуют метаданные (имя поля, имя файла), пустая строка и само содержимое.

Разберем по шагам создание тела запроса в коде 1С:


// Считываем файл в двоичные данные
ПутьКФайлу = "C:\temp\document.pdf";
ФайлДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);

// Начинаем формировать текстовую часть тела
ТекстТела = "--" + Граница + Символы.ПС;
ТекстТела = ТекстТела + "Content-Disposition: form-data; name=""file""; filename=""document.pdf""" + Символы.ПС;
ТекстТела = ТекстТела + "Content-Type: application/pdf" + Символы.ПС + Символы.ПС;

// Преобразуем текст в двоичные данные (используя UTF-8)
ДвоичныеДанныеНачала = ПолучитьДвоичныеДанныеИзСтроки(ТекстТела, КодировкаТекста.UTF8, Ложь);

// Формируем завершающий разделитель
ТекстЗавершения = Символы.ПС + "--" + Граница + "--" + Символы.ПС;
ДвоичныеДанныеКонца = ПолучитьДвоичныеДанныеИзСтроки(ТекстЗавершения, КодировкаТекста.UTF8, Ложь);

// Соединяем все части в один поток
МассивЧастей = Новый Массив;
МассивЧастей.Добавить(ДвоичныеДанныеНачала);
МассивЧастей.Добавить(ФайлДвоичныеДанные);
МассивЧастей.Добавить(ДвоичныеДанныеКонца);

ПолноеТелоЗапроса = ОбъединитьДвоичныеДанные(МассивЧастей);
Запрос.УстановитьТелоИзДвоичныхДанных(ПолноеТелоЗапроса);

Обратите внимание на использование функции ОбъединитьДвоичныеДанные. Это наиболее эффективный способ сборки больших запросов, так как он минимизирует использование оперативной памяти по сравнению с конкатенацией строк или использованием ЗаписьДанных.

Шаг 4: Выполнение и анализ результата

После того как объект HTTPЗапрос полностью укомплектован заголовками и телом, мы отправляем его на сервер. Проанализируем ситуацию получения ответа. Нам важно проверить код состояния (HTTP Status Code), чтобы убедиться в успешности операции.


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

Важным моментом является использование блока Попытка...Исключение. Ошибки могут возникнуть на уровне сетевого протокола (отсутствие интернета, таймаут, неверный адрес), и их необходимо корректно обрабатывать, чтобы программа не завершилась аварийно.

Дополнительные рекомендации

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

  1. Таймауты: При отправке больших файлов стандартный таймаут может быть недостаточен. Устанавливайте его в конструкторе HTTPСоединение (параметр в секундах).
  2. Кодировка: Всегда явно указывайте КодировкаТекста.UTF8 при преобразовании строк в двоичные данные, так как серверы чаще всего ожидают именно эту кодировку.
  3. Метод POST: Убедитесь, что сервер поддерживает именно multipart/form-data. Некоторые API требуют передачи файла в теле напрямую (binary stream) без разделителей. В этом случае достаточно просто использовать Запрос.УстановитьТелоИзФайла(ПутьКФайлу).
  4. Прокси-сервер: Если работа ведется из закрытой корпоративной сети, не забудьте настроить параметры прокси в объекте HTTPСоединение.

Мы рассмотрели универсальный и наиболее гибкий способ отправки файлов. Данный подход позволяет передавать не только сам файл, но и дополнительные текстовые поля в одном запросе, просто добавляя новые секции между разделителями boundary.

← На главную