Как реализовать хранение картинок на внешнем сайте и их отображение в 1С по ссылке

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

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

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

Постановка задачи и архитектурный подход

Прежде чем переходить к написанию кода, определим общую архитектурную схему решения. Вместо хранения двоичных данных в стандартных таблицах базы данных (например, в справочнике Файлы или табличных частях номенклатуры) мы выполняем следующие действия:

  1. Добавляем в справочник Номенклатура (или в отдельный связанный справочник/регистр сведений) строковый реквизит, например, СсылкаНаКартинку с длиной от 250 до 1000 символов.
  2. В этот реквизит записываем прямой URL-адрес картинки на веб-сервере (например, https://mysite.ru/images/goods/item_1025.jpg).
  3. При открытии карточки товара или при прокрутке динамического списка система должна динамически считывать эту ссылку, получать файл из интернета и показывать его пользователю.

Решение 1. Использование поля HTML-документа (универсальный метод)

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

Разберем по шагам, как настроить отображение через HTML:

  1. Добавим на форму карточки номенклатуры новый реквизит формы с типом Строка и назовем его, например, АдресКартинкиHTML.
  2. Перетащим этот реквизит на форму и установим для него вид элемента: Поле HTML-документа.
  3. В процедуре при чтении данных на сервере или при открытии формы будем генерировать простой HTML-код с тегом <img>, где атрибут src указывает на наш URL.

Рассмотрим пример кода для инициализации поля HTML-документа:


&НаСервере
Процедура ОбновитьКартинкуНаФормеНаСервере()
    
    СсылкаНаКартинку = Объект.СсылкаНаКартинку; // Наш реквизит с URL
    
    Если ЗначениеЗаполнено(СсылкаНаКартинку) Тогда
        // Формируем простейший HTML-контейнер с масштабированием изображения под размеры поля
        СтрокаHTML = "<html>
                     |<body style=""margin:0; padding:0; overflow:hidden; background-color: #F0F0F0;"">
                     |<img src=""" + СсылкаНаКартинку + """ style=""width:100%; height:100%; object-fit: contain;"" />
                     |</body>
                     |</html>";
    Иначе
        // Отображаем пустую заглушку, если ссылка отсутствует
        СтрокаHTML = "<html><body style=""margin:0; padding:0;""><p style=""text-align:center; padding-top:20%; color:gray;"">Картинка отсутствует</p></body></html>";
    КонецЕсли;
    
    АдресКартинкиHTML = СтрокаHTML;
    
КонецПроцедуры

Преимущества метода: простота реализации, автоматическая обработка сетевых протоколов встроенным браузером операционной системы, нет необходимости сохранять файлы на жесткий диск пользователя.

Недостатки: зависимость от настроек системного браузера, возможные проблемы с контекстным меню веб-страницы при клике на поле и отсутствие прямого контроля над кэшированием.

Решение 2. Асинхронное скачивание файла и вывод через стандартное «Поле картинки»

Более профессиональным и «чистым» с точки зрения интерфейса 1С является отображение картинки через стандартный элемент управления «Поле картинки». Для этого нам потребуется скачать файл во временную папку компьютера пользователя, поместить его во временное хранилище и привязать к элементу формы.

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

Для решения этой проблемы мы применим асинхронные методы платформы 1С 8.3. Разберем этот алгоритм по шагам:


&НаКлиенте
Асинх Процедура ПриОткрытии(Отказ)
    
    Ожидать ЗагрузитьКартинкуАсинхронно();
    
КонецПроцедуры

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

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

Решение 3. Организация локального кэширования картинок на стороне клиента

Постоянное скачивание одной и той же картинки по сети при каждом открытии карточки товара или при перемещении по динамическому списку создает колоссальную нагрузку на веб-сервер и сетевой канал офиса. Чтобы этого избежать, мы настоятельно рекомендуем разработать простой механизм локального кэширования файлов на компьютерах пользователей.

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

  1. При запросе картинки система генерирует уникальное имя файла для кэша на основе URL-адреса. Для этого отлично подойдет вычисление хэш-функции MD5 от строки URL-адреса.
  2. Программа проверяет, существует ли файл с таким именем в локальном каталоге кэша пользователя (например, в каталоге временных файлов).
  3. Если файл найден на диске, он мгновенно считывается из локального кэша без обращений к интернету.
  4. Если файла на диске нет, программа скачивает его по сети, сохраняет в папку кэша для будущих обращений и выводит на экран.

Проанализируем пример кода с функцией кэширования:


&НаКлиенте
Функция ПолучитьКартинкуИзКэшаИлиСети(УРЛАдрес) Экспорт
    
    Если Не ЗначениеЗаполнено(УРЛАдрес) Тогда
        Возврат "";
    КонецЕсли;
    
    // Шаг 1: Создаем каталог кэша в папке временных файлов пользователя
    КаталогКэша = КаталогВременныхФайлов() + "1C_Image_Cache\";
    СоздатьКаталог(КаталогКэша);
    
    // Шаг 2: Получаем уникальное имя файла по хэшу URL-адреса
    ИмяФайлаКэша = КаталогКэша + ПолучитьИмяФайлаПоХэшу(УРЛАдрес) + ".jpg";
    
    ФайлНаДиске = Новый Файл(ИмяФайлаКэша);
    
    // Шаг 3: Проверка наличия файла в кэше
    Если ФайлНаДиске.Существует() Тогда
        Возврат ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяФайлаКэша));
    КонецЕсли;
    
    // Шаг 4: Если в кэше нет — скачиваем из сети
    Попытка
        КопироватьФайл(УРЛАдрес, ИмяФайлаКэша);
        Возврат ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяФайлаКэша));
    Исключение
        // В случае ошибки возвращаем пустую строку или заглушку "Файл не найден"
        Возврат "";
    КонецПопытки;
    
КонецФункции

&НаКлиенте
Функция ПолучитьИмяФайлаПоХэшу(СтрокаURL)
    // Функция преобразует URL в хэш MD5 для уникального и валидного имени файла
    Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
    Хеш.Добавить(СтрокаURL);
    Возврат Строка(Хеш.ХешСумма);
КонецФункции

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

Решение 4. Массовая загрузка картинок по ссылкам из прайс-листов Excel

В первом сообщении темы автор упоминает необходимость загрузки данных из внешних Excel-файлов. При импорте товаров из Excel, содержащего ссылки на изображения, ни в коем случае нельзя скачивать файлы интерактивно в цикле обработки строк на клиенте. Процесс импорта тысяч позиций заблокирует сеанс работы пользователя на несколько часов.

Правильным подходом будет перенос задачи импорта картинок в фоновое задание на сервере:

  1. Пользователь загружает файл Excel, система парсит строки и создает элементы справочника Номенклатура с заполненным текстовым полем СсылкаНаКартинку.
  2. Сразу после создания карточки товара 1С запускает фоновое задание на сервере, передавая ему массив созданных ссылок.
  3. Фоновое задание в цикле на сервере обращается к сайту, скачивает оригиналы, проверяет их доступность и, при необходимости, генерирует превью-версии изображений меньшего размера для отображения в мобильных приложениях или веб-витринах.

Современный тренд: Переход от FTP-папок сайта к S3-совместимым облачным хранилищам

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

Для хранения файлов вне базы 1С сегодня рекомендуется использовать современные S3-совместимые объектные облачные хранилища (например, Yandex Object Storage, MinIO, AWS S3 и др.). Интеграция 1С с объектными облаками предоставляет важные преимущества:

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

← На главную