При интеграции интернет-магазина или личного кабинета с 1С часто возникает задача: передать не только текстовые данные заказа (структуру JSON), но и сопутствующий файл, например, спецификацию или счет в формате PDF. Существует несколько способов реализации этой задачи, каждый из которых имеет свои преимущества и ограничения. Рассмотрим подробнее наиболее эффективные подходы.
Это самый простой в реализации способ, так как он позволяет передать все данные в рамках одного стандартного POST-запроса. Проанализируем механику: бинарные данные PDF-файла преобразуются в текстовую строку по алгоритму Base64 и помещаются в одно из полей вашего JSON-объекта.
Преимущества:
Недостатки:
Основной минус заключается в увеличении объема передаваемых данных. Как было отмечено в обсуждении, каждые 3 байта двоичных данных превращаются в 4 символа текста. Таким образом, размер файла увеличивается примерно на 33%. Если ваши PDF-файлы весят несколько мегабайт, это может существенно нагрузить канал связи.
Для реализации в 1С используем метод Base64Значение() для обратного преобразования:
// Пример обработки входящего JSON с Base64 в 1С
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТелоЗапросаТекст);
ДанныеЗаказа = ПрочитатьJSON(ЧтениеJSON);
Если ДанныеЗаказа.Свойство("ФайлBase64") Тогда
ДвоичныеДанныеФайла = Base64Значение(ДанныеЗаказа.ФайлBase64);
ДвоичныеДанныеФайла.Записать("C:\Temp\order_spec.pdf");
КонецЕсли;
Этот архитектурный подход считается более профессиональным для высоконагруженных систем. Вместо того чтобы передавать тяжелый файл «внутри» запроса, сайт сначала загружает его в облачное хранилище или временную папку на веб-сервере, а в 1С отправляет только URL-ссылку.
Разберем ситуацию: 1С получает легкий JSON, быстро создает заказ и ставит задачу в очередь (или фоновое задание) на скачивание файла по указанному адресу. Это позволяет избежать «подвисания» HTTP-сервиса на время передачи большого объема данных.
Проанализируем алгоритм работы:
id_заказа и url_файла.HTTPСоединение.Получить() и сохраняет файл.Это стандартный способ передачи файлов в протоколе HTTP, который используют браузеры при отправке форм. В этом случае тело запроса разделяется на части (parts) специальным разделителем (boundary). Одна часть содержит JSON, другая — чистые бинарные данные PDF.
Важный нюанс: В 1С при работе с HTTPСервисЗапрос нет встроенного удобного парсера для multipart/form-data. Вам придется вручную разбирать тело запроса, используя ПолучитьТелоКакБинарныеДанные(), искать границы разделов и вырезать нужные куски данных. Это более трудозатратно в плане написания кода, но максимально эффективно по использованию трафика, так как PDF передается байт-в-байт без оверхеда Base64.
Выясним причину, по которой часто выбирают разделение запросов. Если файл очень большой, вероятность сбоя при передаче возрастает. Поэтому логично сначала создать «карточку» заказа, а затем отдельным методом передать файл, привязав его к ID созданного заказа.
Пример структуры API:
POST /api/v1/orders — создание заказа, возвращает GUID.POST /api/v1/orders/{GUID}/file — передача PDF-файла в теле запроса (Binary).В этом случае на стороне 1С метод приема файла будет выглядеть очень просто, так как всё тело запроса — это и есть ваш PDF:
// Метод HTTP-сервиса для приема файла
Функция ПринятьФайл(Запрос)
ИмяФайла = Запрос.ПараметрыURL.Получить("GUID") + ".pdf";
ДвоичныеДанные = Запрос.ПолучитьТелоКакБинарныеДанные();
ДвоичныеДанные.Записать(ПутьКХранилищу + ИмяФайла);
Возврат Новый HTTPСервисОтвет(200);
КонецФункции
Независимо от выбранного метода, необходимо учитывать настройки веб-сервера (IIS, Apache или Nginx), который стоит перед 1С. По умолчанию они часто ограничивают размер POST-запроса (например, 2 Мб или 8 Мб). Если PDF-файл окажется больше, запрос будет отсечен сервером еще до того, как попадет в 1С, и вы получите ошибку 413 Payload Too Large.
Рекомендация: Если файлы небольшие (до 1-2 Мб), используйте Base64 внутри JSON для простоты. Если файлов много или они тяжелые — используйте передачу по ссылке или Multipart/form-data для экономии ресурсов сервера и трафика.