Как решить проблему с отображением картинок в HTML-письмах из 1С?

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

При разработке механизмов отправки писем из среды 1С программисты часто сталкиваются с неприятной ситуацией. Мы создаем красивый HTML-макет в конфигураторе, вставляем туда изображения, пишем код для отправки, но получатель открывает письмо в Microsoft Outlook, Gmail или через веб-интерфейс почтового сервиса и видит лишь пустые рамки с красными крестиками вместо картинок. В этой статье мы подробно разберем, почему так происходит, и рассмотрим три надежных способа решения этой проблемы.

Выясняем причину: почему картинки «бьются»?

Когда мы загружаем картинку в HTML-макет в конфигураторе 1С, платформа сохраняет ее во внутренней структуре временных файлов макета. В самом HTML-коде генерируется относительный путь, который выглядит примерно так: <img src="8eb4fad1-1fa6-403e-970f-2c12dbb43e23_files/1.png" />.

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

Существует несколько ошибочных подходов к решению этой проблемы, которые часто выбирают начинающие разработчики:

  1. Использование внешнего хостинга картинок. Мы можем выгрузить картинки на наш сайт или публичный хостинг картинок и прописать абсолютные ссылки вида src="https://mycompany.com/images/logo.png". Это рабочий метод, но у него есть существенный минус: большинство современных почтовых клиентов по умолчанию блокируют загрузку внешних изображений в целях конфиденциальности (чтобы отправитель не мог отследить факт открытия письма). Получателю придется вручную нажимать кнопку «Разрешить загрузку картинок», что портит внешний вид письма.
  2. Кодирование в Base64 (Data URI). Способ, при котором бинарный код картинки внедряется прямо в HTML-код тега: src="data:image/png;base64,iVBORw...". В обычном браузере это работает превосходно. Однако многие почтовые сервисы (например, Outlook и Gmail) полностью вырезают или блокируют Base64-код из соображений безопасности (в него можно внедрить вредоносный скрипт) и для предотвращения раздувания размера писем.

Единственным общепринятым мировым стандартом отправки писем с изображениями является технология Content-ID (CID). Картинка прикрепляется к письму как скрытое вложение (MIME-part), а в HTML-коде мы ссылаемся на нее с помощью конструкции src="cid:ИдентификаторКартинки". Разберем три практических способа реализации этого механизма в 1С.

Способ 1. Автоматический метод с использованием ОбработатьТексты()

Разработчики платформы 1С предусмотрели встроенный интеллектуальный механизм, который может самостоятельно проанализировать HTML-код письма, найти в нем ссылки на локальные файлы, автоматически упаковать их во вложения и связать через cid.

Давайте разберем этот процесс по шагам. Главное условие для работы этого метода: в HTML-коде письма пути к картинкам должны быть указаны как абсолютные локальные пути на сервере 1С (начиная с префикса file:///).

Рассмотрим пример программного кода, реализующий этот подход:


// Шаг 1. Получаем текст HTML из макета
МакетХТМЛ = УправлениеОтчетами.ПолучитьМакет("НашМакетПисьма");
ТекстHTML = МакетХТМЛ.ПолучитьТекст();

// Шаг 2. Сохраняем картинки из макета на диск сервера во временную папку
// Предположим, мы программно выгрузили картинку во временный файл
ПутьККартинкеНаДиске = ПолучитьИмяВременногоФайла("png");
ДвоичныеДанныеКартинки = ПолучитьКартинкуИзБазы(); // Ваша функция получения данных
ДвоичныеДанныеКартинки.Записать(ПутьККартинкеНаДиске);

// Шаг 3. Заменяем относительный путь в HTML-тексте на абсолютный файловый путь
ПутьДляHTML = "file:///" + СтрЗаменить(ПутьККартинкеНаДиске, "\", "/");
ТекстHTML = СтрЗаменить(ТекстHTML, "8eb4fad1-1fa6-403e-970f-2c12dbb43e23_files/1.png", ПутьДляHTML);

// Шаг 4. Формируем интернет-почтовое сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Тестовое письмо с картинками";
Письмо.Отправитель.Адрес = "sender@company.com";
Письмо.Получатели.Добавить("recipient@client.com");

// Важно: добавляем текст именно с указанием типа HTML
Письмо.Тексты.Добавить(ТекстHTML, ТипТекстаПочтовогоСообщения.HTML);

// Шаг 5. Запускаем автоматическую обработку текстов
Письмо.ОбработатьТексты();

// Платформа сама найдет файл по пути "file:///", прикрепит его во вложения, 
// сгенерирует уникальный CID и заменит путь в HTML на "cid:..."

Использование метода ОбработатьТексты() избавляет разработчика от ручной рутины, связанной с парсингом тегов <img> и генерацией уникальных идентификаторов. Платформа делает все операции под капотом.

Способ 2. Ручной метод сопоставления через Идентификатор вложения

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

Для этого в HTML-макете мы сразу прописываем статический идентификатор в теге картинки. Посмотрим на пример разметки в макете:


<p>Здравствуйте! Благодарим за покупку в нашем магазине.</p>
<img src="cid:CompanyLogo" alt="Наш Логотип" style="width: 200px; height: auto;" />
<p>С уважением, отдел продаж.</p>

Обратите внимание на значение атрибута src="cid:CompanyLogo". Нам не нужно динамически менять эту строчку в коде 1С. Все, что нам требуется — это добавить картинку во вложения письма и явно назначить ей этот же идентификатор.

Проанализируем пример кода на стороне 1С:


Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Ваш заказ успешно оформлен!";
Письмо.Отправитель.Адрес = "sales@company.com";
Письмо.Получатели.Добавить("customer@email.com");

// Устанавливаем готовый HTML-текст со статичным cid
Письмо.Тексты.Добавить(ПолучитьТекстHTMLМакета(), ТипТекстаПочтовогоСообщения.HTML);

// Получаем двоичные данные картинки (например, из макета или из хранилища значений)
ДвоичныеДанныеЛоготипа = ПолучитьДвоичныеДанныеЛоготипа(); 

// Добавляем двоичные данные во вложения сообщения
ВложениеЛоготип = Письмо.Вложения.Добавить(ДвоичныеДанныеЛоготипа, "logo.png");

// Ключевой момент: связываем вложение с HTML-кодом по идентификатору!
ВложениеЛоготип.Идентификатор = "CompanyLogo";

Этот способ работает невероятно быстро, надежно и поддерживается абсолютно всеми почтовыми клиентами. Главное — следить за уникальностью идентификаторов, если в письме используется несколько разных картинок.

Способ 3. Использование объекта ФорматированныйДокумент

Если ваши пользователи самостоятельно создают письма во встроенном текстовом редакторе 1С (в режиме Предприятия), вставляют туда картинки из буфера обмена или загружают файлы с локального компьютера, то структура HTML формируется динамически. Для работы с такими данными в платформе 1С существует специальный объект — ФорматированныйДокумент.

Данный объект обладает встроенным методом ПолучитьHTML(), который умеет разделять визуальное представление документа на чистый HTML-код и структуру картинок. Разберем по шагам, как это запрограммировать:


// Предположим, у нас на форме есть реквизит "ТекстПисьма" с типом ФорматированныйДокумент
ПереданныйТекстHTML = "";
СтруктураКартинок = Новый Структура;

// Метод разделяет текст и изображения
ТекстПисьма.ПолучитьHTML(ПереданныйТекстHTML, СтруктураКартинок);

// Создаем почтовое сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Письмо из редактора";
Письмо.Отправитель.Адрес = "info@company.com";
Письмо.Получатели.Добавить("client@domain.com");

// Записываем полученный HTML в тело письма
Письмо.Тексты.Добавить(ПереданныйТекстHTML, ТипТекстаПочтовогоСообщения.HTML);

// Обходим коллекцию выделенных картинок и прикрепляем их во вложения
Для Каждого ЭлементСтруктуры Из СтруктураКартинок Цикл
    
    // Получаем двоичные данные картинки
    ДанныеКартинки = ЭлементСтруктуры.Значение.ПолучитьДвоичныеДанные();
    
    // Имя ключа структуры является сгенерированным cid в полученном HTML
    ИдентификаторКартинки = ЭлементСтруктуры.Ключ;
    
    // Добавляем вложение в письмо
    НовоеВложение = Письмо.Вложения.Добавить(ДанныеКартинки, ИдентификаторКартинки + ".png");
    НовоеВложение.Идентификатор = ИдентификаторКартинки;
    
КонецЦикла;

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

Важные нюансы оформления HTML-писем

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

Применяя описанные методы связывания картинок через Content-ID (cid), вы гарантируете корректное отображение ваших фирменных стилей, логотипов и товарных карточек в любых почтовых сервисах ваших клиентов.

← На главную