Разберем распространенную ситуацию: разработчик формирует табличный документ в 1С, сохраняет его в формат HTML и возвращает полученный текст через HTTP-сервис клиенту. При открытии такого файла локально на сервере все отображается корректно, однако при получении ответа через браузер или стороннее приложение разметка отображается, а все картинки пропадают.
Проанализируем механизм работы платформы при выполнении метода сохранения табличного документа:
ТабличныйДокумент.Записать(ИмяФайлаHTML, ТипФайлаТабличногоДокумента.HTML);
При таком вызове платформа 1С создает не только сам файл разметки с расширением .html, но и отдельную директорию на диске сервера с именем ИмяФайла_files. В эту папку сохраняются все графические элементы, содержащиеся в табличном документе (логотипы, штрихкоды, подписи, печати). В результирующем HTML-коде теги <img> содержат относительные ссылки на локальные файлы в этой подпапке.
Когда HTTP-сервис возвращает клиенту только текст HTML-страницы, браузер на стороне пользователя парсит полученный код и пытается выполнить отдельные HTTP-запросы по указанным относительным путям. Так как в конфигурации 1С для этих путей нет настроенных обработчиков, веб-сервер возвращает ошибку 404 Not Found, и изображения не отображаются.
Рассмотрим наиболее универсальное решение, которое позволяет отдать страницу единым документом без необходимости настраивать дополнительные маршруты на веб-сервере. Для этого заменим относительные пути к файлам картинок на их представление в формате Data URL с кодированием в Base64.
Разберем по шагам реализацию данного алгоритма:
_files.Base64Строка().data:image/png;base64,<СтрокаBase64>.Посмотрим на пример функции для преобразования разметки:
Функция ПолучитьHTMLСВнедреннымиКартинками(ТабличныйДокумент) Экспорт
КаталогВременныхФайлов = КаталогВременныхФайлов();
ИмяФайлаHTML = КаталогВременныхФайлов + "report_" + Строка(Новый УникальныйИдентификатор) + ".html";
ПапкаФайлов = КаталогВременныхФайлов + "report_" + Строка(Новый УникальныйИдентификатор) + "_files";
ТабличныйДокумент.Записать(ИмяФайлаHTML, ТипФайлаТабличногоДокумента.HTML);
ЧтениеТекста = Новый ЧтениеТекста(ИмяФайлаHTML, КодировкаТекста.UTF8);
ТекстHTML = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
ФайлыКартинок = НайтиФайлы(ПапкаФайлов, "*.*");
Для Каждого ФайлКартинки Из ФайлыКартинок Цикл
ДвоичныеДанные = Новый ДвоичныеДанные(ФайлКартинки.ПолноеИмя);
Base64Данные = Base64Строка(ДвоичныеДанные);
Расширение = НРег(ФайлКартинки.Расширение);
Если Расширение = ".jpg" Или Расширение = ".jpeg" Тогда
ТипMIME = "image/jpeg";
ИначеЕсли Расширение = ".png" Тогда
ТипMIME = "image/png";
ИначеЕсли Расширение = ".gif" Тогда
ТипMIME = "image/gif";
Иначе
ТипMIME = "application/octet-stream";
КонецЕсли;
DataURL = "data:" + ТипMIME + ";base64," + Base64Данные;
ОтносительныйПуть = ФайлКартинки.Имя;
ТекстHTML = СтрЗаменить(ТекстHTML, ОтносительныйПуть, DataURL);
УдалитьФайлы(ФайлКартинки.ПолноеИмя);
КонецЦикла;
Попытка
УдалитьФайлы(ПапкаФайлов);
УдалитьФайлы(ИмяФайлаHTML);
Исключение
// Обработка исключения очистки временных файлов
КонецПопытки;
Возврат ТекстHTML;
КонецФункции
Если разработка ведется в типовой или доработанной конфигурации, содержащей Библиотеку стандартных подсистем (БСП), нам не нужно писать парсер вручную. В подсистеме печати уже реализована готовая экспортная процедура:
УправлениеПечатью.ВставитьКартинкиВHTML(ИмяФайлаHTML);
Данная процедура автоматически находит связанную папку с ресурсами, конвертирует все графические элементы в Data URL и перезаписывает исходный HTML-файл. После этого остается лишь прочитать файл в строку и передать в тело ответа через HTTPСервисОтвет.УстановитьТелоИзСтроки().
Если объем изображений велик, встраивание их через Base64 увеличивает размер документа примерно на 33%. В этом случае оптимально отдавать изображения отдельными HTTP-запросами:
HTTPСервис создаем дополнительный шаблон URL, например: /images/{ИмяКартинки}.Content-Type (image/png или image/jpeg).Если формат HTML не является строго обязательным для клиентского приложения, рассмотрим альтернативные варианты выгрузки:
ТипФайлаТабличногоДокумента.PDF) — наиболее надежный формат для отображения печатных форм. Все изображения автоматически упаковываются внутрь одного бинарного файла. В ответе HTTP-сервиса возвращаются двоичные данные с заголовком Content-Type: application/pdf. Большинство современных веб-браузеров отображают PDF встроенными средствами.ТипФайлаТабличногоДокумента.MHT) — веб-архив, содержащий разметку и картинки в одном файле (тип содержимого multipart/related). Однако следует учитывать, что многие современные браузеры скачивают данный формат как файл вместо прямого отображения страницы.