Как передать изображение из мобильного приложения 1С в рабочую базу через HTTP-сервис?

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

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

В этой статье мы подробно разберем, как захватить изображение с камеры смартфона и доставить его в рабочую базу в целости и сохранности, используя оптимальные технические решения.

Метод 1: Прямая передача двоичных данных в теле запроса

Проанализируем наиболее эффективный с точки зрения объема трафика способ — передачу картинки как набора двоичных данных. Этот метод позволяет не тратить ресурсы на кодирование в Base64, которое увеличивает размер пакета примерно на 30%.

На стороне мобильного приложения:

Сначала мы получаем снимок, используя СредстваМультимедиа, затем извлекаем двоичные данные и помещаем их в тело POST-запроса.


// 1. Делаем фотоснимок
Настройки = Новый НастройкиЛокальногоУстройства;
Фото = СредстваМультимедиа.СделатьФотоснимок(ТипКамерыУстройства.Задняя, Настройки, 90);

Если Фото <> Неопределено Тогда
    ДвоичныеДанныеКартинки = Фото.ПолучитьДвоичныеДанные();
    
    // 2. Формируем HTTP-запрос
    Соединение = Новый HTTPСоединение("адрес_сервера", , "логин", "пароль");
    Запрос = Новый HTTPЗапрос("/ваша_база/hs/MyService/v1/upload");
    
    // 3. Устанавливаем двоичные данные в тело запроса
    Запрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеКартинки);
    Запрос.Заголовки.Вставить("Content-Type", "image/jpeg");
    
    Ответ = Соединение.ОтправитьДляОбработки(Запрос);
КонецЕсли;

На стороне основной базы (HTTP-сервис):

В методе POST нашего сервиса мы считываем данные напрямую из запроса.


Функция UploadImage(Запрос)
    // Получаем двоичные данные из тела HTTP-запроса
    ДанныеКартинки = Запрос.ПолучитьТелоКакДвоичныеДанные();
    
    // Далее можно сохранить в справочник или файл
    НоваяКартинка = Справочники.Файлы.СоздатьЭлемент();
    НоваяКартинка.Наименование = "Фото_из_МП_" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss");
    НоваяКартинка.ДанныеФайла = Новый ХранилищеЗначения(ДанныеКартинки);
    НоваяКартинка.Записать();
    
    Возврат Новый HTTPСервисОтвет(200);
КонецФункции

Метод 2: Использование формата Base64 внутри структуры JSON

Выясним ситуацию, когда вместе с картинкой нужно передать дополнительные метаданные: ID документа, комментарий или координаты GPS. В этом случае удобно использовать JSON, а саму картинку преобразовать в строку Base64.

Рассмотрим по шагам реализацию этого подхода:

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

ДанныеИзображения = Base64Строка(Фото.ПолучитьДвоичныеДанные());

ДанныеПакета = Новый Структура;
ДанныеПакета.Вставить("ИмяФайла", "photo.jpg");
ДанныеПакета.Вставить("Данные", ДанныеИзображения);
ДанныеПакета.Вставить("ИдентификаторОбъекта", "УИД_ВАШЕГО_ДОКУМЕНТА");

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

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

Важное замечание: Передачу такого объема данных следует выполнять только через POST запрос. При использовании GET запросов строка Base64 будет обрезана, так как длина URL ограничена веб-серверами.

Сжатие данных для экономии трафика

Если мобильный интернет нестабилен, проанализируем возможность предварительного сжатия данных. Платформа позволяет использовать ХранилищеЗначения с параметром СжатиеДанных. Это особенно полезно при пакетной передаче данных.


&НаСервереБезКонтекста
Функция ПодготовитьСжатыйПакет(Данные)
    // Сжимаем данные с максимальной степенью 9
    СжатыйПакет = Новый ХранилищеЗначения(Данные, Новый СжатиеДанных(9));
    
    // Для передачи через HTTP сериализуем ХранилищеЗначения в XML или JSON
    // (см. пример 13 в обсуждении форума)
    Возврат СжатыйПакет;
КонецФункции

Настройка веб-сервера IIS для приема больших файлов

Часто программисты сталкиваются с тем, что код написан верно, но сервер возвращает ошибку 404 или 413. Разберем причину: по умолчанию IIS (Internet Information Services) ограничивает размер загружаемых данных (обычно до 30 Мб, но иногда лимиты могут быть и жестче).

Чтобы разрешить передачу «тяжелых» фотографий, необходимо отредактировать файл web.config на сервере, где опубликована база:


<system.webServer> 
   <security> 
      <requestFiltering> 
         <requestLimits maxAllowedContentLength="100000000" /> 
      </requestFiltering> 
   </security> 
</system.webServer>

Значение maxAllowedContentLength указано в байтах. В данном примере мы увеличили лимит до ~100 Мб.

Оптимизация изображения перед отправкой (Ресайз)

Современные камеры смартфонов делают снимки разрешением 12–50 Мп. Передавать 10-мегабайтное фото для того, чтобы просто прикрепить его к акту осмотра, нецелесообразно. Мы рекомендуем выполнять ресайз (изменение размера) на стороне мобильного приложения.

Используйте объект Картинка для преобразования:

Рекомендации по стабильности соединения

Поскольку передача файлов — операция длительная, разберем, как сделать работу пользователя комфортной:

  1. Фоновая отправка: Не блокируйте интерфейс мобильного приложения. Сохраните фото в локальную базу данных (например, в регистр сведений или справочник) и запустите ФоновоеЗадание, которое будет пытаться отправить данные.
  2. Очередь сообщений: Если связь пропала, приложение должно сохранить статус «Не отправлено» и повторить попытку при появлении сети.
  3. Тома хранения файлов: В рабочей базе старайтесь не сохранять двоичные данные прямо в SQL. Используйте механизм «Тома хранения файлов», чтобы фотографии хранились на диске сервера, сохраняя базу компактной и быстрой.

Следуя этим шагам, мы создадим надежный и быстрый механизм обмена медиафайлами между мобильными устройствами и центральной системой 1С.

← На главную