Как передать изображение через HTTP-сервис в 1С и сохранить его в базу данных

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

В современной разработке на платформе 1С:Предприятие 8.3 часто возникает задача интеграции различных систем, где требуется передача не только текстовой информации, но и бинарных данных, таких как изображения. Рассмотрим ситуацию, когда нам необходимо передать картинку с клиента на сторону HTTP-сервиса и сохранить её в информационной базе (например, в ресурсе регистра сведений или реквизите справочника). Проанализируем несколько подходов, разберем их преимущества и приведем примеры реализации. Для упрощения разработки серверной части можно использовать готовый общий модуль для организации HTTP-сервисов.

Способ 1. Передача бинарных данных в теле запроса (Binary Stream)

Этот метод считается наиболее производительным и "чистым" с точки зрения использования протокола HTTP. Вместо того чтобы упаковывать файл в дополнительные форматы, мы отправляем "сырые" двоичные данные. Рассмотрим, как реализовать отправку на стороне клиента и получение на стороне сервера.

На стороне клиента мы считываем файл в объект ДвоичныеДанные и помещаем его в тело запроса:


// Клиентский код (отправка)
КартинкаОбъект = Новый Картинка("C:\temp\image.jpg");
ДвоичныеДанные = КартинкаОбъект.ПолучитьДвоичныеДанные();

Запрос = Новый HTTPЗапрос("/hs/MyService/UploadImage");
Запрос.Заголовки.Вставить("Content-Type", "image/jpeg");
Запрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);

Соединение = Новый HTTPСоединение("myserver.com");
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

На стороне HTTP-сервиса в методе POST мы извлекаем данные. Проанализируем, как это сделать правильно:


// Код метода HTTP-сервиса (прием)
Функция UploadImagePost(Запрос)
    
    ДвоичныеДанные = Запрос.ПолучитьТелоКакДвоичныеДанные();
    
    // Проверим, что данные действительно являются картинкой
    Попытка
        ТестоваяКартинка = Новый Картинка(ДвоичныеДанные);
    Исключение
        Возврат Новый HTTPСервисОтвет(400); // Bad Request
    КонецПопытки;
    
    // Сохранение в регистр или справочник
    НоваяЗапись = РегистрыСведений.ХранилищеИзображений.СоздатьМенеджерЗаписи();
    НоваяЗапись.ИмяФайла = "uploaded_image.jpg";
    НоваяЗапись.ДанныеФайла = Новый ХранилищеЗначения(ДвоичныеДанные);
    НоваяЗапись.Записать();
    
    Возврат Новый HTTPСервисОтвет(200);
КонецФункции

Способ 2. Использование JSON и кодирования Base64

Если ваш HTTP-сервис спроектирован по принципам REST и работает с JSON-объектами, наиболее логичным будет передать картинку как одну из строк в JSON. Поскольку JSON не поддерживает бинарные данные напрямую, мы преобразуем их в строку с помощью алгоритма Base64. Стоит учитывать, что это увеличивает размер передаваемых данных примерно на 33%. Для тестирования и отладки создаваемого REST API пригодится инструмент для проверки HTTP-запросов на платформе 1С.

Разберем по шагам процесс упаковки данных:

  1. Получаем ДвоичныеДанные из файла.
  2. Преобразуем их в строку методом Base64Строка().
  3. Формируем структуру JSON.

// Подготовка данных на клиенте
ДвоичныеДанные = Новый ДвоичныеДанные("C:\photo.png");
СтрокаBase64 = Base64Строка(ДвоичныеДанные);

ДанныеДляОтправки = Новый Структура;
ДанныеДляОтправки.Вставить("FileName", "photo.png");
ДанныеДляОтправки.Вставить("Content", СтрокаBase64);

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеДляОтправки);
ТелоЗапроса = ЗаписьJSON.Закрыть();

На стороне сервера выполняем обратную операцию. Мы считываем JSON, извлекаем строку и превращаем её обратно в ДвоичныеДанные с помощью функции Base64Значение().


// Обработка на сервере
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Запрос.ПолучитьТелоКакСтроку());
СтруктураДанных = ПрочитатьJSON(ЧтениеJSON);

Если СтруктураДанных.Свойство("Content") Тогда
    КартинкаБинар = Base64Значение(СтруктураДанных.Content);
    // Далее записываем КартинкаБинар в ХранилищеЗначения
КонецЕсли;

Способ 3. Передача через Multipart/form-data

Выясним причину популярности этого метода: он позволяет передавать одновременно и файлы, и текстовые поля (метаданные) без сложного кодирования всего тела запроса. В 1С это реализуется через формирование составного тела запроса с разделителями (boundary).

Рассмотрим структуру такого запроса. Мы должны вручную или с помощью специализированных библиотек сформировать поток, в котором будут указаны границы частей данных и их типы. Это особенно удобно, если вы загружаете сразу несколько изображений одним пакетом.

Особенности хранения и валидации на сервере

После того как данные получены HTTP-сервисом, важно убедиться в их корректности перед записью в базу. Проанализируем лучшие практики:

Настройка веб-сервера для работы с файлами

Важно помнить, что при работе через HTTP-сервисы запросы проходят через веб-сервер (IIS или Apache). По умолчанию в них стоят ограничения на объем передаваемого тела запроса (часто это 2 МБ или 30 МБ). Если вы попытаетесь передать файл большего размера, 1С даже не получит запрос, так как веб-сервер вернет ошибку 413 Entity Too Large.

Для IIS необходимо отредактировать файл web.config, изменив параметр maxAllowedContentLength. Для Apache следует обратить внимание на директиву LimitRequestBody в конфигурационном файле httpd.conf.

В завершение отметим, что выбор метода зависит от архитектуры вашего решения. Если вы строите универсальное API, используйте JSON + Base64. Если важна максимальная скорость передачи больших файлов — выбирайте Binary Stream. Использование встроенных функций ЗначениеВФайл и ЗначениеИзФайла, как упоминалось в обсуждении, также возможно для быстрой сериализации внутренних объектов 1С, но этот метод менее универсален при взаимодействии с внешними системами.

← На главную