Разработка и Конфигурация · 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 потребует заметной памяти на сервере. Для файлов больше нескольких мегабайт этот вариант лучше не использовать.
Сравнение способов передачи
Минимальный объём и нагрузка. Подходит для больших файлов. Минус: в одном запросе — один файл, метаданные передаются заголовками.
Удобно отлаживать, можно передать файл вместе с произвольными полями. Минус: +33% к объёму, высокий расход памяти на больших файлах.
Стандарт для форм: несколько файлов и полей в одном запросе. Минус: в 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С. Если загрузка обрывается на одном и том же размере, проверяйте настройки веб-сервера в первую очередь.
Как выбрать способ
Типичные ошибки и их диагностика
Большинство проблем при передаче файлов через HTTP-сервисы 1С сводится к нескольким повторяющимся причинам. Их удобно проверять в первую очередь, прежде чем углубляться в отладку кода.
Для диагностики полезно логировать входящие запросы: метод, размер тела, заголовки, результат обработки. В файловом варианте для тестов можно публиковать сервис на локальном 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, проверяйте размер тела и не публикуйте сервис без аутентификации. Контроль целостности — сравнение размера и хеша на обеих сторонах.