При интеграции 1С с внешними API, использующими формат multipart/form-data, разработчики часто сталкиваются с ошибкой 400 Bad Request и сообщением сервера "There was an error parsing the body". Эта проблема возникает из-за строгого соответствия протоколу HTTP (RFC 2045/2046). Давайте разберем, как правильно формировать такие запросы, чтобы сервер корректно принимал ваши файлы.
Первое, что необходимо осознать — это требование стандарта к разделителям строк. В формате multipart/form-data в качестве разделителя должен выступать символ CRLF (Carriage Return + Line Feed). В 1С это соответствует последовательности Символ(13) + Символ(10). Ошибка многих разработчиков заключается в использовании обратного порядка 10 + 13 или использовании только символа ПС (10). Даже если в некоторых случаях сервер «прощает» такие ошибки, при работе с API лучше строго следовать стандарту.
Для корректного разделения данных в теле запроса мы используем уникальную строку Boundary. Важно правильно расставить управляющие символы до и после каждой части данных. Рассмотрим корректный алгоритм формирования запроса.
Вместо того чтобы вручную собирать строки с потенциально неверными символами, воспользуемся объектом ЗаписьДанных. Обратите внимание на то, как мы записываем разделители и данные:
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 + "--");
ЗаписьДанных.Закрыть();
Частой скрытой причиной порчи файла являются невидимые символы BOM, которые 1С может записывать в начало файла при использовании ЗаписьТекста. Если сервер ожидает «чистый» файл, наличие EF BB BF в начале превращает его в «мусор».
Для предотвращения этой проблемы:
ЗаписьДанных, как показано выше — этот метод позволяет избежать нежелательного BOM.ЗаписьТекста, указывайте кодировку "CESU-8", которая для 1С по сути является UTF-8 без BOM.BOM, его можно отсечь, прочитав данные через ДвоичныеДанные и удалив первые 3 байта перед отправкой.Если вы всё еще получаете 400 или другие ошибки:
Postman или Python побайтово.Content-Length (обычно платформа 1С считает его автоматически) или специфический User-Agent.Content-Type: application/pdf; charset=utf-8 внутри части multipart только мешают. Попробуйте передать только минимально необходимые заголовки Content-Disposition.ЗаписьДанных.ЗаписатьСтроку автоматически добавляет CRLF (код 13+10), что является эталоном для HTTP-запросов.Следуя этим шагам, вы сможете успешно реализовать отправку файлов любой сложности, будь то интеграция с Честный ЗНАК, Диадок или вашим внутренним API. Главное правило — работайте с потоками данных и внимательно следите за порядком управляющих символов.