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

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

При интеграции 1С с внешними API, использующими формат multipart/form-data, разработчики часто сталкиваются с ошибкой 400 Bad Request и сообщением сервера "There was an error parsing the body". Эта проблема возникает из-за строгого соответствия протоколу HTTP (RFC 2045/2046). Давайте разберем, как правильно формировать такие запросы, чтобы сервер корректно принимал ваши файлы.

Разбор причин ошибки и важность стандарта CRLF

Первое, что необходимо осознать — это требование стандарта к разделителям строк. В формате multipart/form-data в качестве разделителя должен выступать символ CRLF (Carriage Return + Line Feed). В 1С это соответствует последовательности Символ(13) + Символ(10). Ошибка многих разработчиков заключается в использовании обратного порядка 10 + 13 или использовании только символа ПС (10). Даже если в некоторых случаях сервер «прощает» такие ошибки, при работе с API лучше строго следовать стандарту.

Шаг 1: Правильное формирование разделителя (Boundary)

Для корректного разделения данных в теле запроса мы используем уникальную строку Boundary. Важно правильно расставить управляющие символы до и после каждой части данных. Рассмотрим корректный алгоритм формирования запроса.

Шаг 2: Реализация формирования тела запроса

Вместо того чтобы вручную собирать строки с потенциально неверными символами, воспользуемся объектом ЗаписьДанных. Обратите внимание на то, как мы записываем разделители и данные:


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

ТелоЗапроса = ЗапросWeb.ПолучитьТелоКакПоток();
ЗаписьДанных = Новый ЗаписьДанных(ТелоЗапроса, КодировкаТекста.UTF8, ПорядокБайтов.LittleEndian, , , Ложь);

// Записываем начало части данных
ЗаписьДанных.ЗаписатьСтроку("--" + Boundary);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename=""" + ИмяФайлаДляЗагрузки + """");

// Пустая строка перед бинарными данными обязательна для стандарта
ЗаписьДанных.ЗаписатьСтроку(""); 

// Записываем сам файл
ЗаписьДанных.Записать(дд); 

// Завершаем часть и весь запрос
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку("--" + Boundary + "--");
ЗаписьДанных.Закрыть();

Шаг 3: Проблема BOM (Byte Order Mark)

Частой скрытой причиной порчи файла являются невидимые символы BOM, которые 1С может записывать в начало файла при использовании ЗаписьТекста. Если сервер ожидает «чистый» файл, наличие EF BB BF в начале превращает его в «мусор».

Для предотвращения этой проблемы:

  1. Используйте ЗаписьДанных, как показано выше — этот метод позволяет избежать нежелательного BOM.
  2. Если вы используете ЗаписьТекста, указывайте кодировку "CESU-8", которая для 1С по сути является UTF-8 без BOM.
  3. Если файл уже содержит BOM, его можно отсечь, прочитав данные через ДвоичныеДанные и удалив первые 3 байта перед отправкой.

Рекомендации по отладке

Если вы всё еще получаете 400 или другие ошибки:

Следуя этим шагам, вы сможете успешно реализовать отправку файлов любой сложности, будь то интеграция с Честный ЗНАК, Диадок или вашим внутренним API. Главное правило — работайте с потоками данных и внимательно следите за порядком управляющих символов.

← На главную