Как вернуть картинку и ее описание из HTTP-сервиса 1С?

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

При разработке интеграционных решений на платформе 1С часто возникает задача передать через HTTP-сервис не просто один файл или строку, а комбинированный пакет данных. Например, когда в ответ на запрос сторонней системы необходимо вернуть картинку (двоичные данные) и ее текстовое описание.

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

Решение 1. Передача данных в формате JSON с кодированием в Base64

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

При реализации этого метода важно помнить об ограничениях платформы: метод ЗаписатьJSON() не умеет напрямую сериализовать объект типа ДвоичныеДанные. Нам необходимо предварительно преобразовать двоичные данные файла в строку при помощи встроенной функции Base64Строка().

Разберем пример кода, реализующий этот подход:


Функция ПолучитьКартинкуИОписаниеJSON(Запрос)

    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    
    // Путь к файлу картинки на сервере
    ИмяФайлаКартинки = "C:\MyPictures\image.png"; 
    
    // Читаем файл в двоичные данные и конвертируем в Base64
    ДвоичныеДанныеКартинки = Новый ДвоичныеДанные(ИмяФайлаКартинки);
    СтрокаBase64 = Base64Строка(ДвоичныеДанныеКартинки);
    
    // Формируем структуру ответа
    СтруктураДанных = Новый Структура;
    СтруктураДанных.Вставить("Description", "Это описание нашей картинки, переданное вместе с файлом.");
    СтруктураДанных.Вставить("FileName", "image.png");
    СтруктураДанных.Вставить("ImageBytes", СтрокаBase64);
    
    // Сериализуем структуру в JSON-строку
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);
    СтрокаJSON = ЗаписьJSON.Закрыть();
    
    // Устанавливаем тело ответа
    Ответ.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8);
    
    Возврат Ответ;

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

Преимущества: Простота разбора на стороне получателя (большинство современных языков программирования имеют встроенные средства для работы с JSON и декодирования Base64).

Недостатки: Кодирование бинарных данных в Base64 увеличивает размер передаваемых данных примерно на 33%, что критично при передаче больших файлов или высокой частоте запросов.

Решение 2. Формирование составного ответа (multipart/form-data)

Если принимающая сторона требует передачи "чистых" бинарных данных без избыточного кодирования в Base64, лучшим решением будет использование формата multipart/form-data. В этом случае тело HTTP-ответа делится специальными границами (boundary) на независимые блоки, каждый из которых может иметь свой тип содержимого.

В платформе 1С для побайтовой сборки такого пакета мы можем использовать связку объектов ПотокВПамяти и ЗаписьДанных. Проанализируем пример создания составного сообщения:


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

    Ответ = Новый HTTPСервисОтвет(200);
    
    // Определяем уникальную границу частей сообщения
    Разделитель = "----Boundary1234567890";
    Ответ.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Разделитель);
    
    Поток = Новый ПотокВПамяти;
    Запись = Новый ЗаписьДанных(Поток, КодировкаТекста.UTF8);
    
    // --- ЧАСТЬ 1: Текстовое описание ---
    Запись.ЗаписатьСтроку("--" + Разделитель);
    Запись.ЗаписатьСтроку("Content-Disposition: form-data; name=""description""");
    Запись.ЗаписатьСтроку("Content-Type: text/plain; charset=utf-8");
    Запись.ЗаписатьСтроку(""); // Пустая строка, отделяющая заголовки от данных
    Запись.ЗаписатьСтроку("Описание картинки в текстовом формате.");
    
    // --- ЧАСТЬ 2: Бинарный файл картинки ---
    Запись.ЗаписатьСтроку("--" + Разделитель);
    Запись.ЗаписатьСтроку("Content-Disposition: form-data; name=""image""; filename=""photo.jpg""");
    Запись.ЗаписатьСтроку("Content-Type: image/jpeg");
    Запись.ЗаписатьСтроку(""); // Пустая строка перед бинарными данными
    
    // Сбрасываем текстовый буфер перед записью сырых двоичных данных
    Запись.СброситьБуфер();
    
    // Записываем бинарные данные картинки напрямую в поток
    ДвоичныеДанныеКартинки = Новый ДвоичныеДанные("C:\MyPictures\photo.jpg");
    Запись.Записать(ДвоичныеДанныеКартинки);
    
    // --- Закрывающий разделитель ---
    Запись.ЗаписатьСтроку("");
    Запись.ЗаписатьСтроку("--" + Разделитель + "--");
    Запись.СброситьБуфер();
    
    // Извлекаем собранные данные из потока
    ДвоичныеДанныеОтвета = Поток.ЗакрытьИПолучитьДвоичныеДанные();
    Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеОтвета);
    
    Возврат Ответ;

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

Преимущества: Экономия сетевого трафика и процессорного времени сервера приложений 1С за счет отсутствия перекодирования в Base64.

Недостатки: Код сборки ответа усложняется, принимающая сторона должна уметь корректно парсить составные сообщения multipart/form-data.

Решение 3. Архитектурное разделение запросов (Двухэтапный REST)

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

Рассмотрим логику работы этой схемы:

  1. Клиент отправляет первый запрос к методу HTTP-сервиса (например, GET /api/v1/items/123) и получает легкий JSON-ответ с описанием объекта и уникальным идентификатором картинки (или готовой ссылкой на нее):
    
    {
      "id": 123,
      "description": "Описание товара",
      "image_url": "/api/v1/images/123"
    }
    
  2. Клиент анализирует полученные данные, выводит текст пользователю, а саму картинку загружает вторым отдельным GET-запросом по адресу, указанному в параметре image_url.

Этот метод не только упрощает код 1С, но и позволяет использовать промежуточное кэширование статических бинарных данных на уровне веб-серверов (например, Apache, Nginx или IIS), существенно снижая нагрузку на рабочие процессы платформы 1С.

← На главную