При разработке интеграционных решений на платформе 1С часто возникает задача передать через HTTP-сервис не просто один файл или строку, а комбинированный пакет данных. Например, когда в ответ на запрос сторонней системы необходимо вернуть картинку (двоичные данные) и ее текстовое описание.
Поскольку стандартный объект HTTPСервисОтвет инициализирует тело ответа либо из строки, либо из двоичных данных, мы не можем "просто так" положить в него несколько разнородных объектов. Рассмотрим три надежных и проверенных способа решения этой задачи средствами платформы 1С:Предприятие 8.3.
Это самый распространенный и простой в реализации способ. Мы упаковываем текстовое описание и двоичные данные картинки в одну структуру, предварительно преобразовав картинку в текстовую строку формата 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%, что критично при передаче больших файлов или высокой частоте запросов.
Если принимающая сторона требует передачи "чистых" бинарных данных без избыточного кодирования в 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.
Для высоконагруженных систем оптимальным выбором является разделение получения текстовой информации (метаданных) и бинарных файлов на два независимых этапа.
Рассмотрим логику работы этой схемы:
GET /api/v1/items/123) и получает легкий JSON-ответ с описанием объекта и уникальным идентификатором картинки (или готовой ссылкой на нее):
{
"id": 123,
"description": "Описание товара",
"image_url": "/api/v1/images/123"
}
image_url.Этот метод не только упрощает код 1С, но и позволяет использовать промежуточное кэширование статических бинарных данных на уровне веб-серверов (например, Apache, Nginx или IIS), существенно снижая нагрузку на рабочие процессы платформы 1С.