Как открыть файл из ХранилищаЗначений без записи на диск и настроить внутренние ссылки в HTML в 1С?

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

При разработке систем документооборота и подсистем хранения файлов в 1С часто возникает задача организации доступа к прикрепленным документам. Иногда бизнес-требования или службы безопасности выдвигают жесткое условие: открывать двоичные данные из хранилища значений во внешних приложениях (MS Word, MS Excel, PDF-просмотрщики) строго без сохранения временных файлов на локальный диск пользователя. Вторая сопутствующая проблема — некорректная работа внутренних гиперссылок (якорей с символом #) при выводе HTML-документов непосредственно из строки текста.

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

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

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

  1. Механизмы операционной системы: Внешние редакторы и просмотрщики (такие как MS Office, Adobe Reader и др.) запускаются через системный API операционной системы. Этим программам необходим физический путь к файлу на диске (например, C:\Users\...\AppData\Local\Temp\file.docx). Они не умеют считывать произвольные блоки байтов напрямую из оперативной памяти процесса 1С.
  2. Ограничения Веб-клиента: В браузерном режиме веб-клиент 1С работает внутри изолированной среды («песочницы» браузера). Из соображений безопасности веб-страница не имеет прямого доступа к файловой системе и не может запускать локальные исполняемые файлы клиентского компьютера с передачей им данных из памяти.
  3. Использование COM и ActiveX: Попытки задействовать COM-объекты для управления браузером или приложениями в веб-клиенте либо заблокированы современными браузерами, либо создают серьезные уязвимости безопасности (вектор для атак типа Remote Code Execution и внедрения вредоносного кода).

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

Альтернативные варианты работы с файлами без создания временных файлов

Если бизнес-требование запрещает создавать локальные файлы на диске, рассмотрим способы, которые позволяют отобразить содержимое данных средствами самой платформы 1С или браузера:

  1. Встроенный просмотр средствами 1С:

    Для документов формата PDF, изображений (PNG, JPG) и HTML-страниц можно использовать элемент формы ПолеHTMLДокумента. Данные передаются непосредственно в поле без сохранения на диск (например, через адрес во временном хранилище 1С или Data URI).

    Текстовые и табличные данные можно загружать напрямую в объекты ТекстовыйДокумент или ТабличныйДокумент и выводить их во встроенных редакторах 1С.

  2. Использование HTTP-сервисов 1С:

    Двоичные данные отдаются клиенту по запросу через HTTP-сервис конфигурации. Формируется временная URL-ссылка, по которой браузер или внешний просмотрщик получает поток данных по HTTP-протоколу, избегая явного сохранения файла клиентским кодом 1С.

  3. Штатный метод НачатьСкачиваниеФайла():

    В веб-клиенте передача файла пользователю реализуется через метод НачатьСкачиваниеФайла(). В этом случае браузер самостоятельно принимает поток данных и либо предлагает пользователю сохранить его, либо открывает во встроенном просмотрщике браузера (например, для PDF-файлов).

Решение проблемы с внутренними ссылками (якорями `#`) в Поле HTML документа

Проанализируем вторую проблему: при передаче HTML-кода из строки в элемент формы ПолеHTMLДокумента нажатие на внутренние ссылки (например, <a href="#section1">) приводит к ошибке или открытию пустой страницы.

Причина поведения: Когда HTML-документ формируется из строки кода в памяти, у него отсутствует базовый адрес (Base URI). Движок отображения (WebKit или Chromium) пытаются сопоставить относительную ссылку #section1 со служебным адресом 1С (вида e1c://... или v8config://...), из-за чего навигация ломается.

Выясним, как устранить эту проблему несколькими способами:

Способ 1. Указание тега `` в HTML-коде

Самый простой способ — добавить в блок <head> загружаемого HTML-документа тег <base> с условным базовым адресом. Это позволяет браузерному движку корректно определять якоря внутри документа.


ТекстHTML = "<html>
|head>
|	<base href=""about:blank"">
|</head>
|<body>
|	<a href=""#anchor1"">Перейти к разделу 1</a>
|	<div style=""height:1000px;""></div>
|	<h2 id=""anchor1"">Раздел 1</h2>
|</body>
|</html>";

Элементы.ПолеHTML.УстановитьТекст(ТекстHTML);

Способ 2. Использование JavaScript для прокрутки к якорю

Вместо стандартной навигации по гиперссылкам href="#id" можно использовать обработку нажатия через JavaScript-метод scrollIntoView(), который отменяет стандартный переход браузера:


<a href="#" onclick="document.getElementById('anchor1').scrollIntoView(); return false;">Перейти к разделу 1</a>

Способ 3. Перехват события `ПриНажатии` на стороне 1С

Если HTML-код нельзя редактировать на этапе формирования, можно перехватить нажатие на гиперссылку в событии элемента формы ПолеHTMLДокумента:


&НаКлиенте
Процедура ПолеHTMLПриНажатии(Элемент, ДанныеСобытия, Отказ)
	
	// Проверяем, является ли ссылка внутренним якорем
	Если ДанныеСобытия <> Неопределено И Найти(ДанныеСобытия.Href, "#") > 0 Тогда
		Отказ = Истина; // Отменяем штатную навигацию 1С
		
		// Получаем идентификатор якоря и выполняем прокрутку через DOM
		ИмяЯкоря = Сред(ДанныеСобытия.Href, Найти(ДанныеСобытия.Href, "#") + 1);
		Элемент.Документ.getElementById(ИмяЯкоря).scrollIntoView();
	КонецЕсли;

КонецПроцедуры

Подводя итог: открывать файлы во внешних приложениях без записи во временный каталог на диске невозможно в силу архитектурных ограничений ОС и требований безопасности. Для работы в веб-клиенте следует использовать штатные просмотрщики 1С, HTTP-сервисы или скачивание файлов, а проблемы навигации в HTML-документах решает явное указание тега <base> или перехват событий DOM.

← На главную