К статье
Практический материал

Разработка и Конфигурация · 10 мин

1С HTTP-сервис: как передать файл

Как передать файл через HTTP-сервис в 1С: приём и отдача файлов, base64 и двоичные данные, примеры кода, ограничения и типичные ошибки.

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

Выбор способа зависит от размера файла, возможностей внешней системы и требований к надёжности. Небольшие файлы удобно передавать в Base64 внутри JSON — так проще отлаживать. Крупные файлы лучше передавать как двоичные данные в теле запроса или через multipart/form-data, чтобы не раздувать объём и не терять память сервера.

Ниже разобраны оба направления: приём файла в HTTP-сервисе 1С и отдача файла клиенту, с рабочими примерами кода, ограничениями и типичными ошибками.

Как HTTP-сервис 1С работает с телом запроса

Объект HTTPСервисЗапрос, доступный в обработчике шаблона URL, предоставляет три способа чтения тела: ПолучитьТелоКакСтроку(), ПолучитьТелоКакДвоичныеДанные() и ПолучитьТелоКакПоток(). Симметрично объект HTTPСервисОтвет позволяет установить тело строкой, двоичными данными или потоком.

Ключевой момент: тело можно прочитать только один раз и только одним методом. Если вызвать ПолучитьТелоКакСтроку() для запроса с бинарным содержимым, данные будут испорчены перекодировкой. Поэтому способ чтения должен соответствовать тому, как клиент реально отправляет файл, — это фиксируется в договорённости интеграции и обычно сопровождается заголовком Content-Type.

Для ответа важно правильно выставить заголовки: Content-Type (например, application/pdf или application/octet-stream) и при необходимости Content-Disposition: attachment; filename="...", чтобы браузер или клиентская система сохранила файл под осмысленным именем.

Приём файла как двоичных данных в теле запроса

Самый прямой сценарий: клиент отправляет POST-запрос, где тело — это сам файл, а имя и тип передаются в заголовках или параметрах URL. В обработчике шаблона тело читается методом ПолучитьТелоКакДвоичныеДанные(), после чего данные сохраняются во временный файл, записываются в хранилище значения реквизита или передаются дальше.

Типовой код обработчика выглядит так:

Функция ЗагрузитьФайлPOST(Запрос)

ДвоичныеДанные = Запрос.ПолучитьТелоКакДвоичныеДанные();

ИмяФайла = Запрос.ПараметрыURL.Получить("ИмяФайла");

// Пример: сохранение в реквизит справочника

НовыйФайл = Справочники.ПрисоединенныеФайлы.СоздатьЭлемент();

НовыйФайл.Наименование = ИмяФайла;

НовыйФайл.ДанныеФайла = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));

НовыйФайл.Записать();

Ответ = Новый HTTPСервисОтвет(200);

Ответ.УстановитьТелоИзСтроки("{""id"": """ + НовыйФайл.Ссылка.УникальныйИдентификатор() + """}");

Ответ.Заголовки.Вставить("Content-Type", "application/json");

Возврат Ответ;

КонецФункции

Обратите внимание на проверку размера: перед записью стоит сравнить ДвоичныеДанные.Размер() с допустимым лимитом и вернуть код 413 (Payload Too Large), если файл слишком велик. Это защищает сервер от переполнения памяти и диска.

Передача файла в Base64 внутри JSON

Когда внешняя система умеет работать только с JSON, файл кодируется в Base64 и передаётся строковым полем. В 1С для этого используются функции Base64Строка() и Base64Значение(): первая превращает двоичные данные в строку, вторая — декодирует обратно.

Пример приёма файла из JSON-тела:

ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку();

ЧтениеJSON = Новый ЧтениеJSON;

ЧтениеJSON.УстановитьСтроку(ТелоЗапроса);

Данные = ПрочитатьJSON(ЧтениеJSON);

ЧтениеJSON.Закрыть();

ДвоичныеДанные = Base64Значение(Данные.fileContent);

ИмяФайла = Данные.fileName;

Способ удобен для отладки — запрос можно посмотреть глазами в любом REST-клиенте. Но помните про накладные расходы: файл 10 МБ превратится примерно в 13–14 МБ текста, а разбор большого JSON потребует заметной памяти на сервере. Для файлов больше нескольких мегабайт этот вариант лучше не использовать.

Сравнение способов передачи

Двоичные данные в теле

Минимальный объём и нагрузка. Подходит для больших файлов. Минус: в одном запросе — один файл, метаданные передаются заголовками.

Base64 в JSON

Удобно отлаживать, можно передать файл вместе с произвольными полями. Минус: +33% к объёму, высокий расход памяти на больших файлах.

multipart/form-data

Стандарт для форм: несколько файлов и полей в одном запросе. Минус: в 1С нет встроенного разбора multipart — тело придётся парсить вручную по boundary.

Отдача файла из 1С внешней системе

Обратная задача — GET-запрос, по которому сервис возвращает файл. Двоичные данные извлекаются из хранилища значения или читаются с диска методом Новый ДвоичныеДанные(ПутьКФайлу), после чего устанавливаются в тело ответа:

Функция СкачатьФайлGET(Запрос)

Идентификатор = Запрос.ПараметрыURL.Получить("id");

Ссылка = Справочники.ПрисоединенныеФайлы.ПолучитьСсылку(

Новый УникальныйИдентификатор(Идентификатор));

ДвоичныеДанные = Ссылка.ДанныеФайла.Получить();

Если ДвоичныеДанные = Неопределено Тогда

Возврат Новый HTTPСервисОтвет(404);

КонецЕсли;

Ответ = Новый HTTPСервисОтвет(200);

Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);

Ответ.Заголовки.Вставить("Content-Type", "application/octet-stream");

Ответ.Заголовки.Вставить("Content-Disposition",

"attachment; filename*=UTF-8''" + Ссылка.Наименование);

Возврат Ответ;

КонецФункции

Для кириллических имён файлов используйте формат filename*=UTF-8'' с URL-кодированием — простое filename="отчёт.pdf" многие клиенты отобразят кракозябрами. Если файл отдаётся часто и не меняется, добавьте заголовки кэширования, чтобы снизить нагрузку на сервер.

Ограничения, потоки и большие файлы

Методы ПолучитьТелоКакДвоичныеДанные() и УстановитьТелоИзДвоичныхДанных() загружают весь файл в память сеанса. При файлах в десятки и сотни мегабайт это приводит к росту потребления памяти рабочими процессами и к тайм-аутам. Для таких сценариев используйте потоковые варианты: ПолучитьТелоКакПоток() на приёме и УстановитьИмяФайлаТела() на отдаче — последний отдаёт файл с диска без загрузки в память.

Дополнительные ограничения задаёт веб-сервер: у IIS и Apache есть собственные лимиты на размер тела запроса, и они могут быть меньше того, что готова принять 1С. Если загрузка обрывается на одном и том же размере, проверяйте настройки веб-сервера в первую очередь.

Маршрут решения

Как выбрать способ

Файл до 1–2 МБ и внешняя система работает с JSONПередавайте Base64-строкой в поле JSON — проще отладка и совместимость.
Файл больше нескольких мегабайт или файлов многоИспользуйте двоичные данные в теле запроса или потоковое чтение/запись.
Нужно передать несколько файлов с полями за один запросРеализуйте multipart/form-data с ручным разбором тела по boundary.
Файл отдаётся с диска сервера и может быть большимИспользуйте УстановитьИмяФайлаТела() вместо загрузки в двоичные данные.

Типичные ошибки и их диагностика

Большинство проблем при передаче файлов через HTTP-сервисы 1С сводится к нескольким повторяющимся причинам. Их удобно проверять в первую очередь, прежде чем углубляться в отладку кода.

Типичные ошибки
01
Чтение тела строкой вместо двоичных данных — файл повреждается перекодировкой и не открывается у получателя.
02
Отсутствует или неверный Content-Type в ответе — клиент сохраняет PDF как текст или не распознаёт файл.
03
Имя файла с кириллицей в Content-Disposition без UTF-8-кодирования — кракозябры в имени при скачивании.
04
Не проверен размер тела — большой файл кладёт сеанс по памяти или упирается в лимит веб-сервера.
05
Тело читается дважды или после частичного чтения — второй вызов возвращает пустоту.
06
HTTP-сервис опубликован без аутентификации — посторонние могут загружать и скачивать файлы.

Для диагностики полезно логировать входящие запросы: метод, размер тела, заголовки, результат обработки. В файловом варианте для тестов можно публиковать сервис на локальном Apache и проверять запросы через curl или Postman, прежде чем подключать реальную внешнюю систему.

Контрольные точки

Как проверить результат

Целостность файла
Норма

Размер и хеш (MD5/SHA) совпадают на отправителе и получателе

Тревожный признак

Размер отличается или файл не открывается

Заголовки ответа
Норма

Content-Type соответствует типу файла, имя читается корректно

Тревожный признак

application/octet-stream там, где нужен конкретный тип; кракозябры в имени

Повторная загрузка
Норма

Сервис корректно обрабатывает повтор и не создаёт дублей или обрабатывает их по правилам

Тревожный признак

Каждый повтор создаёт новый элемент без контроля

FAQ

Как передать несколько файлов одним запросом?

Используйте либо multipart/form-data с ручным разбором тела по строке boundary, либо архив: клиент упаковывает файлы в ZIP, а 1С распаковывает его объектом ЧтениеZipФайла. Второй вариант обычно проще и надёжнее.

Почему файл после передачи не открывается или «битый»?

Чаще всего тело запроса прочитано как строка вместо двоичных данных, либо при Base64-передаче строка содержит переносы строк или обрезана. Проверьте совпадение размера и хеша файла до и после передачи.

Есть ли ограничение на размер передаваемого файла?

Жёсткого лимита в самой платформе нет, но практические границы задают память сеанса, тайм-ауты и настройки веб-сервера (IIS/Apache). Для больших файлов применяйте потоковые методы и УстановитьИмяФайлаТела().

Как проверить HTTP-сервис без внешней системы?

Опубликуйте сервис на тестовом веб-сервере и отправьте запрос из curl, Postman или Insomnia. Для двоичной отправки в curl используется параметр --data-binary @путь_к_файлу с заголовком Content-Type.

Нужна ли аутентификация для HTTP-сервиса, передающего файлы?

Да. Минимум — базовая аутентификация пользователя 1С или проверка токена в заголовке внутри обработчика. Сервис без аутентификации позволяет любому загружать данные в базу и скачивать файлы.

Чем потоковая передача лучше двоичных данных?

Потоки не загружают файл целиком в память: ПолучитьТелоКакПоток() читает тело порциями, а УстановитьИмяФайлаТела() отдаёт файл с диска напрямую. Это критично при файлах в десятки мегабайт и выше.

Итог

Что важно запомнить

Небольшие файлы передавайте в Base64 внутри JSON, крупные — двоичными данными или потоками. Всегда выставляйте корректный Content-Type, кодируйте кириллические имена в Content-Disposition, проверяйте размер тела и не публикуйте сервис без аутентификации. Контроль целостности — сравнение размера и хеша на обеих сторонах.