Как отобразить картинки из интернета на форме 1С без задержек

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

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

Метод 1: Использование Поля HTML-документа

Рассмотрим самый простой и логичный способ отображения картинки из интернета — использование элемента формы Поле HTML-документа. Этот метод позволяет платформе делегировать загрузку и отображение встроенному движку браузера (WebKit или Chromium в зависимости от версии платформы), что максимально приближает поведение 1С к обычному браузеру.

Разберем по шагам, как это реализовать:

  1. Добавим на форму реквизит с типом Строка (неограниченной длины).
  2. Вытащим этот реквизит на форму и установим ему вид Поле HTML-документа.
  3. Сформируем HTML-код, который будет содержать ссылку на нашу картинку.

Проанализируем пример кода для формирования строки HTML:


&НаСервере
Функция СформироватьHTMLДляКартинки(СсылкаНаКартинку)
    
    ТекстHTML = "<html>
    |<head>
    |<style>
    |   body { margin: 0; padding: 0; overflow: hidden; }
    |   img { width: 100%; height: auto; object-fit: contain; }
    |</style>
    |</head>
    |<body>
    |   <img src=""" + СсылкаНаКартинку + """>
    |</body>
    |</html>";
    
    Возврат ТекстHTML;
    
КонецФункции

Этот способ хорош тем, что мы фактически не скачиваем файл средствами 1С. Браузерный движок сам управляет кешированием и потоками загрузки. Однако, если нам нужно отобразить картинки в списке (например, в каждой строке динамического списка), создание множества полей HTML может негативно сказаться на производительности.

Метод 2: Оптимизированная загрузка через КопироватьФайл

Выясним причину, по которой стандартные функции БСП (Библиотеки Стандартных Подсистем), такие как ПолучениеФайловИзИнтернетаСлужебный.СкачатьФайл(), могут работать медленно. Обычно это связано с большим количеством проверок: настройка прокси, проверка сертификатов SSL, логирование и анализ заголовков. Если вы уверены в источнике картинок, можно использовать «лайфхак» с методом КопироватьФайл.

Как оказалось, функция КопироватьФайл в 1С умеет принимать в качестве первого параметра URL-адрес. Это работает значительно быстрее, так как выполняется на более низком уровне системы. Посмотрим на пример реализации:


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

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

Метод 3: Использование HTTP-запросов и двоичных данных

Проанализируем ситуацию, когда нам нужно получить данные картинки напрямую в память. Для этого лучше всего подходят объекты HTTPСоединение и HTTPЗапрос. Это позволяет нам получить ДвоичныеДанные и сразу создать из них объект Картинка, минуя стадию записи временного файла на диск.

Рассмотрим пример кода:


&НаСервере
Функция ПолучитьКартинкуВПамять(URLКартинки)
    
    // Разберем URL на составляющие
    СтруктураURL = ОбщегоНазначенияКлиентСервер.РазложитьУРЛ(URLКартинки);
    
    // Настроим защищенное соединение, если это HTTPS
    НС = Новый ЗащищенноеСоединениеOpenSSL();
    Соединение = Новый HTTPСоединение(СтруктураURL.Хост, , , , , , НС);
    
    Запрос = Новый HTTPЗапрос(СтруктураURL.ПутьНаСервере);
    
    Попытка
        Ответ = Соединение.Получить(Запрос);
        Если Ответ.КодСостояния = 200 Тогда
            ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
            Картинка = Новая Картинка(ДвоичныеДанные);
            Возврат ПоместитьВоВременноеХранилище(Картинка, ЭтаФорма.УникальныйИдентификатор);
        КонецЕсли;
    Исключение
        Возврат Неопределено;
    КонецПопытки;
    
    Возврат Неопределено;
    
КонецФункции

Этот метод является максимально «чистым» с точки зрения архитектуры 1С, так как мы полностью контролируем процесс запроса и не оставляем «мусора» на диске сервера или клиента.

Секреты оптимизации: Асинхронность и Кеширование

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

  1. Асинхронная загрузка: Начиная с версии 8.3.18, в 1С активно развиваются асинхронные вызовы. Вместо блокирующего метода Соединение.Получить() можно использовать Соединение.ВызватьHTTPМетодАсинх(). Это позволит форме отрисоваться сразу, а картинки будут «подтягиваться» по мере загрузки.
  2. Кеширование во временном хранилище: Чтобы не скачивать одну и ту же картинку дважды (например, при обновлении формы), создайте на клиенте Соответствие, где ключом будет URLКартинки, а значением — АдресВоВременномХранилище.

Посмотрим, как можно реализовать простую систему кеширования на форме:


&НаКлиенте
Перем КэшКартинок;

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    КэшКартинок = Новый Соответствие;
КонецПроцедуры

&НаКлиенте
Асинх Процедура ЗагрузитьКартинкуДляСтроки(URL, ИдентификаторСтроки)
    
    // Проверим, нет ли ссылки в кеше
    Адрес = КэшКартинок.Получить(URL);
    
    Если Адрес = Неопределено Тогда
        // Загружаем асинхронно с сервера
        Адрес = Ждать ПолучитьАдресКартинкиСервер(URL);
        КэшКартинок.Вставить(URL, Адрес);
    КонецЕсли;
    
    // Обновляем данные на форме
    Элементы.ТаблицаТоваров.ДанныеСтроки(ИдентификаторСтроки).КартинкаПуть = Адрес;
    
КонецПроцедуры

Итоги и рекомендации

Подводя итог, можно выделить следующие рекомендации по работе с картинками из интернета:

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

← На главную