Почему не отображаются картинки в поле HTML документа в клиент-серверном варианте и как это исправить?

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

При разработке прикладных решений на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда поле HTML документа отлично отображает графику в файловом варианте базы, но «теряет» её при переходе на клиент-серверный вариант. Особенно остро эта проблема проявилась в последних релизах платформы (начиная с 8.3.21 и выше, включая 8.3.27), где механизмы безопасности стали значительно строже. Разберем подробно, почему это происходит и какие существуют методы решения данной задачи.

Анализ проблемы: клиент-серверное взаимодействие и безопасность

Для начала проанализируем ситуацию, описанную в сообщениях форума. Основная причина того, что картинка не отображается в клиент-серверном варианте, заключается в разделении контекстов исполнения. Когда мы формируем HTML-код на стороне сервера, мы оперируем путями к файлам, которые доступны серверу (например, временные папки пользователя, под которым запущен сервер 1С). Однако само поле HTML документа — это визуальный компонент, который отрисовывается на стороне клиента (в тонком или толстом клиенте).

Рассмотрим типичный сценарий: сервер формирует файл картинки в своей временной папке C:\Users\USR1CV8\AppData\Local\Temp\... и вставляет этот путь в тег <img>. Когда клиентское приложение пытается отобразить этот HTML, оно ищет файл по указанному пути на локальном компьютере пользователя. Естественно, там этого файла нет, и пользователь видит «пустой квадрат».

Ситуация осложняется в новых версиях платформы (8.3.21, 8.3.24, 8.3.27). Платформа перешла на обновленный движок Chromium. В целях безопасности встроенный браузер теперь блокирует загрузку любых ресурсов по протоколу file://. Даже если вы программно передадите файл с сервера на клиент и положите его в локальную папку пользователя, при попытке подставить прямой путь в HTML вы получите ошибку: «В целях безопасности загрузка по файловому протоколу заблокирована».

Решение №1: Использование Base64 (самый надежный метод)

Проанализируем наиболее универсальный способ, который рекомендуют опытные разработчики. Чтобы не зависеть от файловой системы клиента или сервера и обойти ограничения протокола file://, мы можем внедрить данные картинки непосредственно в тело HTML-кода в виде строки. Для этого используется кодирование Base64.

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

Посмотрим на пример кода, который реализует этот механизм:


// 1. Получаем двоичные данные из хранилища или файла
ДвоичныеДанныеКартинки = Справочники.Изображения.ПолучитьДанные(СсылкаНаКартинку); 

// 2. Преобразуем в строку Base64
СтрокаBase64 = Base64Строка(ДвоичныеДанныеКартинки);

// 3. Формируем текст HTML с внедренной картинкой
// Необходимо указать MIME-тип (например, image/jpeg или image/png)
ТекстHTML = "<html><body>";
ТекстHTML = ТекстHTML + "<img src=""data:image/jpeg;base64," + СтрокаBase64 + """ />";
ТекстHTML = ТекстHTML + "</body></html>";

// 4. Устанавливаем текст в поле HTML документа
Элементы.ПолеHTMLПросмотр.УстановитьТекст(ТекстHTML);

Преимущества этого метода:

  1. Полная независимость от местонахождения файлов.
  2. HTML-документ становится «автономным»: его можно передавать между сервером и клиентом как обычную строку.
  3. Отсутствие проблем с правами доступа к папкам Temp.
  4. Обход блокировок протокола file:// в новых версиях платформы.

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

Решение №2: Передача файлов на клиент и использование временных путей

Рассмотрим альтернативный вариант, который обсуждался в сообщениях. Если по каким-то причинам Base64 вам не подходит, необходимо обеспечить физическое наличие файла на клиентской машине. Однако помните о блокировках платформы 8.3.27! Этот метод будет работать стабильно только в старых релизах или при специфических настройках.

Алгоритм действий следующий:

  1. На сервере помещаем файл картинки во временное хранилище с помощью функции ПоместитьВоВременноеХранилище.
  2. Передаем адрес хранилища на клиент.
  3. На клиенте (в процедуре &НаКлиенте) получаем данные из хранилища и записываем их в локальный временный файл.

Пример реализации передачи:


&НаСервере
Функция ПодготовитьКартинкуНаСервере()
    КартинкаОбъект = Справочники.Файлы.НайтиПоНаименованию("Логотип").Данные.Получить();
    Возврат ПоместитьВоВременноеХранилище(КартинкаОбъект, ЭтаФорма.УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура ОтобразитьHTML()
    АдресХранилища = ПодготовитьКартинкуНаСервере();
    
    // Получаем путь к временному файлу на стороне КЛИЕНТА
    ИмяФайла = ПолучитьИмяВременногоФайла("jpg");
    Данные = ПолучитьИзВременногоХранилища(АдресХранилища);
    Данные.Записать(ИмяФайла);
    
    // Внимание: на новых платформах прямой путь может быть заблокирован!
    ТекстHTML = "... <img src=""" + ИмяФайла + """> ...";
    Элементы.ПолеHTML.УстановитьТекст(ТекстHTML);
КонецПроцедуры

Проблема навигационных ссылок (e1cib/data) в новых платформах

В сообщении №10 пользователь отмечает, что раньше отлично работал метод с навигационными ссылками вида e1cib/data/Справочник.Изображения.Данные?ref=.... Это был очень удобный способ, так как платформа сама брала на себя заботу о доставке данных.

Проанализируем ситуацию: начиная с версии 8.3.21, из-за перехода на Chromium, механизм изоляции содержимого поля HTML стал жестче. Прямая подстановка ссылки e1cib в тег img часто приводит к тому, что картинка не отрисовывается, так как контекст безопасности браузера внутри 1С не считает эту ссылку доверенной или доступной без явной авторизации внутри сессии браузера.

Как быть в версии 8.3.27?

Если навигационные ссылки перестали работать, самым правильным решением будет вернуться к Решению №1 (Base64). Это единственный способ гарантировать отображение картинки во всех вариантах работы: тонкий клиент, толстый клиент и веб-клиент.

Особенности работы в Веб-клиенте

Если ваша задача включает поддержку веб-клиента, следует помнить о правилах CORS (Cross-Origin Resource Sharing). Браузер (Chrome, Firefox) не позволит загрузить картинку с другого домена или локального диска. В этом случае Base64 также является фаворитом. Однако навигационные ссылки e1cib в веб-клиенте обычно работают лучше, чем в тонком клиенте, так как браузер уже находится в контексте веб-сервера 1С.

Резюме и рекомендации

Подводя итог нашему разбору, выделим ключевые правила для работы с графикой в HTML-полях 1С:

Использование данных подходов позволит вам создавать надежные и визуально привлекательные интерфейсы, которые будут стабильно работать вне зависимости от режима запуска или версии платформы 1С.

← На главную