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

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

При разработке конфигураций на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда функционал, идеально работающий в толстом или тонком клиенте, отказывается функционировать в веб-клиенте. Одной из таких задач является отображение PDF-файлов непосредственно в форме документа с помощью поля HTML-документа. Рассмотрим, почему стандартный подход через навигационные ссылки e1cib часто выдает ошибку "Не удалось загрузить PDF-документ", и разберем несколько надежных способов решения этой проблемы.

Анализ проблемы: почему не работает e1cib

В толстом клиенте 1С использует внутренние механизмы рендеринга (часто базирующиеся на движке Internet Explorer), которые понимают протокол e1cib. Однако, когда мы открываем базу через браузер (Chrome, Firefox, Safari), мы попадаем в песочницу безопасности браузера. Современные браузеры блокируют попытки тегов <embed> или <iframe> загрузить данные по внутренним ссылкам 1С, так как они не являются стандартными URL. Кроме того, браузер не всегда может корректно передать авторизационные куки сессии 1С внутрь объекта <embed>, что приводит к ошибке доступа.

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

Способ 1: Передача данных через Base64 (Data URI)

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

Рассмотрим пример реализации на сервере:


&НаСервере
Процедура ЗагрузитьPDFВПолеHTML()
    // Получаем двоичные данные из присоединенного файла или хранилища значений
    ДвоичныеДанные = Объект.ДанныеРезюме.Получить(); 
    
    Если ДвоичныеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Преобразуем двоичные данные в строку Base64
    СтрокаBase64 = Base64Строка(ДвоичныеДанные);
    
    // Формируем HTML-текст с использованием Data URI
    // Используем iframe, так как он лучше поддерживается мобильными браузерами
    ТекстHTML = "<html><body style='margin:0; padding:0;'>";
    ТекстHTML = ТекстHTML + "<iframe src='data:application/pdf;base64," + СтрокаBase64 + "' width='100%' height='100%' style='border:none;'></iframe>";
    ТекстHTML = ТекстHTML + "</body></html>";
    
    // Реквизит формы, связанный с полем HTML-документа
    Объект.ПолеHTML = ТекстHTML;
КонецПроцедуры

Важный нюанс: метод Base64 отлично подходит для небольших документов (до 5–10 Мб). Если PDF-файл очень объемный, строка Base64 станет огромной, что может привести к зависанию формы при передаче данных с сервера на клиент или к ограничениям браузера по длине URL.

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

Выясним, как сделать отображение PDF максимально "профессиональным". Этот метод заключается в создании собственного HTTP-сервиса внутри вашей конфигурации, который будет отдавать файл по стандартному HTTP-адресу. Это снимает все проблемы с безопасностью браузеров.

Рассмотрим алгоритм действий:

  1. Создадим в метаданных HTTP-сервис (например, с именем GetPDF).
  2. Добавим шаблон URL: /view/{FileID}.
  3. В методе GET напишем код, который извлекает файл по его идентификатору и возвращает его в теле ответа.

Пример кода метода GET в HTTP-сервисе:


Функция viewGet(Запрос)
    ИдентификаторФайла = Запрос.ПараметрыШаблона.Получить("FileID");
    
    // Логика получения данных файла из базы
    ДвоичныеДанные = ПолучитьФайлИзХранилища(ИдентификаторФайла); 
    
    Результат = Новый HTTPСервисОтвет(200);
    Результат.Заголовки.Вставить("Content-Type", "application/pdf");
    // Установка Content-Disposition: inline заставляет браузер открыть файл внутри, а не скачивать
    Результат.Заголовки.Вставить("Content-Disposition", "inline; filename=""document.pdf""");
    Результат.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);
    
    Возврат Результат;
КонецФункции

Теперь в поле HTML достаточно передать обычную ссылку на ваш сервис: <iframe src="/ВашаБаза/hs/GetPDF/view/ID_файла"></iframe>. Браузер воспримет это как обычный PDF-ресурс и задействует встроенный просмотрщик.

Способ 3: Интеграция библиотеки PDF.js

Если нам нужно обеспечить одинаковое отображение PDF во всех браузерах (даже если в браузере пользователя отключены плагины для PDF), проанализируем вариант с использованием библиотеки PDF.js от Mozilla. Это "золотой стандарт" для веб-разработки.

Для этого выполним следующие действия:

  1. Скачаем библиотеку PDF.js и добавим ее файлы в конфигурацию как Общие макеты (тип "Двоичные данные").
  2. В HTML-поле сформируем структуру, которая загружает скрипты библиотеки.
  3. Передадим данные файла в библиотеку через временное хранилище или тот же Base64.

Преимущество этого метода в том, что вы получаете полный контроль над интерфейсом просмотра: кнопками печати, масштабирования и поиска, которые будут выглядеть одинаково в Chrome, Safari и Firefox.

Способ 4: Современный подход через Blob и JavaScript

Посмотрим на наиболее производительный способ для современных браузеров, который минимизирует объем передаваемого HTML-текста. Мы можем передать двоичные данные на клиент и создать так называемую Blob-ссылку с помощью JavaScript.

Пример реализации в модуле формы:


&НаКлиенте
Процедура ПоказатьPDF(РезультатЗагрузки)
    // Предположим, мы получили адрес во временном хранилище
    АдресФайла = РезультатЗагрузки.Адрес;
    
    // В поле HTML у нас загружена заготовка со скриптом
    ТекстJS = "
    | var xhr = new XMLHttpRequest();
    | xhr.open('GET', '" + АдресФайла + "', true);
    | xhr.responseType = 'blob';
    | xhr.onload = function(e) {
    |     if (this.status == 200) {
    |         var blob = new Blob([this.response], {type: 'application/pdf'});
    |         var url = URL.createObjectURL(blob);
    |         document.getElementById('pdf-frame').src = url;
    |     }
    | };
    | xhr.send();";
    
    Элементы.ПолеHTML.ВыполнитьСкрипт(ТекстJS);
КонецПроцедуры

Резюме и рекомендации

Подведем итоги нашего исследования. Выбор метода зависит от архитектуры вашей системы:

Важный совет: не забывайте про расширение работы с файлами. Хотя автор темы упоминал ПодключитьРасширениеРаботыСФайлами(), помните, что оно отвечает за взаимодействие с файловой системой пользователя (выгрузка/загрузка), но никак не влияет на отображение PDF внутри браузера. За рендеринг отвечает исключительно движок браузера или подключенные JS-библиотеки.

← На главную