При отправке электронных писем в формате HTML из среды «1С:Предприятие» разработчики часто сталкиваются с неприятной ошибкой: «Ошибка доступа к файлу... Ошибка работы с Интернет: Удаленный узел не прошел проверку». Данная неполадка возникает в тех случаях, когда тело письма содержит теги <img> со ссылками на картинки, расположенные на сторонних серверах по защищенному протоколу HTTPS (например, на популярных хостингах изображений или в социальных сетях).
В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем механизмы работы платформы 1С с защищенными соединениями и рассмотрим несколько эффективных способов решения проблемы — от простых системных настроек до надежных программных алгоритмов.
Прежде чем переходить к устранению проблемы, выясним её первопричину. Когда мы формируем объект ИнтернетПочтовоеСообщение, заполняем его HTML-текстом и вызываем отправку через ИнтернетПочта.Послать(), платформа 1С по умолчанию пытается выполнить предварительную подготовку письма. В ходе этого процесса встроенный почтовый клиент 1С парсит HTML-код, находит все внешние изображения в тегах <img> и пытается самостоятельно скачать их во временное хранилище на сервере 1С, чтобы затем автоматически прикрепить к письму в качестве вложений. Это делается для того, чтобы получатель письма мог увидеть картинки даже при отсутствии интернета.
Если картинка доступна по протоколу HTTPS, платформа 1С инициирует защищенное SSL/TLS-соединение с удаленным сервером для скачивания файла. На этом этапе и происходит сбой. Ошибка «Удаленный узел не прошел проверку» означает, что платформа 1С не смогла подтвердить подлинность SSL-сертификата удаленного веб-сервера. Это может происходить по следующим причинам:
rphost) запускается под системной учетной записью (например, USR1CV8), у которой может быть закрыт доступ к системному хранилищу сертификатов Windows или ограничен выход в интернет для проверки актуальных списков отзыва (CRL/OCSP).cacert.pem, который со временем устаревает и перестает поддерживать новые корневые сертификаты.Ниже мы подробно рассмотрим пять практических вариантов решения этой проблемы.
Рассмотрим первый способ, предложенный разработчиками на практике. Его суть заключается в том, чтобы перехватить процесс обработки картинок до того, как его начнет выполнять сама платформа 1С. Мы можем самостоятельно найти все теги изображений с HTTPS-ссылками, скачать файлы на диск сервера с помощью защищенного HTTP-соединения (где можно гибко настроить игнорирование ошибок SSL) и подставить локальные пути во временные файлы.
Для реализации этого подхода выполним разбор текста письма по шагам с использованием регулярных выражений:
Функция ЗаменитьВсеТэгиИзображенийCHttps(ТекстХТМЛ)
МассивВременныхФайлов = Новый Массив;
RegExp = ОбщегоНазначения.ПолучитьКомпанентуРаботыСРегулярнымиВыражениями();
// Находим все теги картинок, содержащие защищенные ссылки
RegExp.Pattern = "<IMG.*https.*?>";
Для каждого Тэг Из RegExp.Execute(ТекстХТМЛ) Цикл
// Выделяем непосредственно адрес ссылки из атрибута src
RegExp.Pattern = "src="".*?""";
Для каждого ТекстСсылки Из RegExp.Execute(Тэг.Value) Цикл
СсылкаДляСкачивания = СтрЗаменить(ТекстСсылки.Value, "src=""", "");
СсылкаДляСкачивания = СтрЗаменить(СсылкаДляСкачивания, """", "");
// Генерируем уникальное имя временного файла с нужным расширением
Расширение = ПолучитьРасширениеФайлаИзСсылки(СсылкаДляСкачивания);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла(Расширение);
// Скачиваем файл через специализированный веб-сервис или HTTPСоединение
ОтветЛок = СкачатьФайлПоСертификату(СсылкаДляСкачивания, ИмяВременногоФайла);
Если ОтветЛок = "" Тогда
// Заменяем внешнюю HTTPS ссылку в HTML-тексте на локальный путь к файлу
ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ, СсылкаДляСкачивания, ИмяВременногоФайла);
МассивВременныхФайлов.Добавить(ИмяВременногоФайла);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат Новый Структура("ТекстХТМЛ, МассивВременныхФайлов", ТекстХТМЛ, МассивВременныхФайлов);
КонецФункции
Этот метод полностью рабочий, однако он требует ручной очистки временных файлов из массива после того, как отправка письма будет успешно завершена. Также он достаточно ресурсоемок из-за постоянных дисковых операций записи и чтения временных файлов.
Если вам не требуется физически внедрять картинки внутрь письма и вы согласны с тем, что получатель загрузит их из интернета при открытии письма, можно полностью отключить автоматический парсинг картинок платформой 1С. В этом случае 1С не будет пытаться скачать файлы по HTTPS, а отправит HTML-код в исходном виде.
Проанализируем, как это сделать программно. При вызове метода Послать() объекта ИнтернетПочта вторым параметром передается способ обработки текста письма. Нам нужно явно передать значение системного перечисления СпособОбработкиТекстаПисьма.НеОбрабатывать:
// Создаем профиль и подключение к почте
Почта = Новый ИнтернетПочта;
Профиль = Новый ИнтернетПочтовыйПрофиль;
// ... (заполнение настроек профиля) ...
// Формируем сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Тестовое письмо с внешними картинками";
Письмо.УстановитьТекст(ТекстHTMLПисьма, СпособТекстаЭлектронногоПисьма.HTML);
// Отправляем БЕЗ предварительного анализа картинок платформой
Почта.Подключиться(Профиль);
Почта.Послать(Письмо, СпособОбработкиТекстаПисьма.НеОбрабатывать);
Почта.Отключиться();
При таком подходе письмо отправляется мгновенно, нагрузка на сервер 1С минимальна, а проверка SSL-сертификатов перекладывается на почтового клиента получателя (например, Яндекс.Почту, Mail.ru или Microsoft Outlook).
Если вам обязательно нужно, чтобы 1С сама скачивала картинки и внедряла их в тело письма, необходимо сделать так, чтобы платформа доверяла SSL-сертификату удаленного узла. Рассмотрим три основных системных шага для решения этой задачи.
Шаг A. Обновление встроенного файла cacert.pem в платформе 1С
Если платформа 1С работает в режиме совместимости со старыми версиями, она проверяет сертификаты через локальный файл-хранилище. Чтобы обновить его:
C:\Program Files\1cv8\8.3.XX.XXXX\bin\.cacert.pem.Шаг Б. Установка корневых сертификатов в операционную систему
Если сервер 1С работает под управлением ОС Windows, он может использовать системное хранилище. Нам необходимо импортировать корневой сертификат удаленного сайта в доверенные на уровне компьютера:
certlm.msc от имени администратора).USR1CV8), есть права на чтение этого хранилища.Шаг В. Отключение жесткой проверки отзывов в conf.cfg
Часто сам сертификат является доверенным, но сервер 1С из соображений безопасности пытается проверить списки его отзыва через интернет. Если сервер 1С находится в изолированном сегменте сети без прямого доступа к внешнему миру, эта проверка зависает и возвращает ошибку. Чтобы решить эту проблему, откройте конфигурационный файл 1С conf.cfg (он лежит в папке C:\Program Files\1cv8\conf\) и добавьте в него следующую строку:
IgnoreServerCertificatesChainRevocationSoftFail=true
Эта директива указывает платформе игнорировать ошибки проверки списков отзывов, если сервера отзывов недоступны, что решает большинство проблем в закрытых корпоративных сетях.
Рассмотрим наиболее профессиональный и надежный программный метод интеграции картинок в тело письма. Чтобы избежать зависимости от сторонних серверов и протоколов HTTPS, мы можем хранить картинки прямо внутри базы 1С (или в локальной папке сервера) и связывать их с HTML-кодом через специальный идентификатор контента — Content-ID (CID).
Выясним, как реализовать этот алгоритм по шагам:
<img src="cid:идентификатор_картинки" />.Посмотрим на практический пример реализации этого метода:
// 1. Создаем объект сообщения
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Письмо с гарантированным отображением картинок";
// 2. Формируем HTML-текст с использованием cid:
ТекстHTML = "<html><body>";
ТекстHTML = ТекстHTML + "<h1>Приветствуем вас!</h1>";
ТекстHTML = ТекстHTML + "<p>Ниже представлен наш логотип:</p>";
ТекстHTML = ТекстHTML + "<img src=""cid:company_logo_cid"" width=""200"" />";
ТекстHTML = ТекстHTML + "</body></html>";
Письмо.УстановитьТекст(ТекстHTML, СпособТекстаЭлектронногоПисьма.HTML);
// 3. Получаем бинарные данные картинки (из макета, файла или базы данных)
ПутьККартинке = "C:\Pictures\logo.png";
ДвоичныеДанныеКартинки = Новый ДвоичныеДанные(ПутьККартинке);
// 4. Добавляем картинку во вложения и привязываем ее к CID
Вложение = Письмо.Вложения.Добавить(ДвоичныеДанныеКартинки, "logo.png");
Вложение.Идентификатор = "company_logo_cid";
// 5. Отправляем в режиме БЕЗ автоматической обработки (поскольку мы все связали сами)
Почта = Новый ИнтернетПочта;
// ... (подключение почты) ...
Почта.Послать(Письмо, СпособОбработкиТекстаПисьма.НеОбрабатывать);
Этот способ является промышленным стандартом. Картинка гарантированно отобразится у получателя в любом почтовом клиенте (даже при отсутствии подключения к интернету на его устройстве), а сервер 1С не будет инициировать никаких небезопасных внешних HTTPS-сессий.
Еще один альтернативный способ передать изображение внутри HTML-кода без использования внешних ссылок и механизма вложений — это кодирование бинарных данных картинки в строку формата Base64. Полученную строку мы можем внедрить прямо в атрибут src тега <img>.
Проанализируем структуру такого тега:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." />
Для программной реализации этого метода в 1С используется объект Base64Строка. Посмотрим на пример кода:
// Кодируем локальный файл картинки в Base64 строку
ДвоичныеДанныеКартинки = Новый ДвоичныеДанные("C:\Pictures\logo.png");
СтрокаBase64 = Base64Строка(ДвоичныеДанныеКартинки);
// Удаляем символы переноса строк, если они присутствуют
СтрокаBase64 = СтрЗаменить(СтрокаBase64, Символы.ПС, "");
СтрокаBase64 = СтрЗаменить(СтрокаBase64, Символы.ВК, "");
// Формируем HTML со встроенным изображением
ТекстHTML = "<html><body>";
ТекстHTML = ТекстHTML + "<img src=""data:image/png;base64," + СтрокаBase64 + """ />";
ТекстHTML = ТекстHTML + "</body></html>";
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.УстановитьТекст(ТекстHTML, СпособТекстаЭлектронногоПисьма.HTML);
// Отправляем строго с параметром НеОбрабатывать
Почта.Послать(Письмо, СпособОбработкиТекстаПисьма.НеОбрабатывать);
Важное предупреждение: При использовании этого метода обязательно отправляйте письмо со свойством СпособОбработкиТекстаПисьма.НеОбрабатывать. Если этого не сделать, парсер 1С попытается воспринять длинную Base64-строку как локальный путь к файлу на диске компьютера, что приведет к ошибке выполнения «Файл не обнаружен». Также помните, что некоторые устаревшие почтовые программы не поддерживают отображение картинок в формате Base64 из соображений безопасности, поэтому метод с использованием CID (Решение 4) остается более предпочтительным.
Мы подробно изучили природу ошибки проверки удаленного узла SSL в 1С и разобрали различные методы борьбы с ней. Выбор оптимального решения зависит от архитектуры вашей системы: