Почему поле HTML-документа в веб-клиенте 1С возвращает undefined и как это исправить

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

При разработке интерфейсов на платформе 1С:Предприятие 8.3 часто возникает задача интеграции внешнего веб-контента в управляемые формы. Мы привыкли, что в тонком или толстом клиенте обращение к объектной модели (DOM) загруженной страницы происходит прозрачно через свойство Документ. Однако при переходе в веб-клиент многие разработчики сталкиваются с тем, что это же свойство возвращает Неопределено (undefined). В этой статье мы подробно разберем, почему это происходит, проанализируем механизмы безопасности современных браузеров и найдем эффективные способы решения задачи.

Причина проблемы: Политика единого источника (Same-Origin Policy)

Для начала выясним причину, по которой 1С ведет себя по-разному в разных клиентах. Когда мы запускаем тонкий клиент, платформа использует встроенный движок (WebKit или движок Internet Explorer), который работает в контексте операционной системы как полновесное приложение. В этом случае 1С имеет полный контроль над компонентом и может беспрепятственно обращаться к любым свойствам загруженного контента.

Рассмотрим ситуацию в веб-клиенте. Здесь сама 1С работает внутри браузера (Chrome, Firefox, Safari). Поле HTML-документа в веб-клиенте превращается в обычный HTML-тег <iframe>. Здесь в силу вступает Same-Origin Policy (SOP) — фундаментальная модель безопасности веб-контента. Браузер запрещает скриптам, находящимся на одной странице (ваша база 1С, например, https://1c.company.com), обращаться к содержимому фрейма, если он загружен с другого домена (например, https://google.com). Если протокол, домен или порт не совпадают, доступ к свойству document внутри iframe будет заблокирован на уровне ядра браузера. Именно поэтому 1С возвращает Неопределено: она просто не может пробиться сквозь защиту браузера.

Способ 1. Использование метода ВыполнитьJavaScript

Начиная с версии платформы 8.3.14, фирма «1С» рекомендует отказываться от прямого обращения к DOM через свойство Документ в пользу асинхронного или синхронного выполнения скриптов. Метод ВыполнитьJavaScript() является более универсальным, так как он позволяет передать команду внутрь контекста страницы.

Проанализируем ситуацию: нам нужно получить данные из поля ввода на сторонней странице. Вместо того чтобы писать Элементы.ПолеHTML.Документ.getElementById(...), мы будем использовать внедрение кода. Рассмотрим пример:


// В контексте управляемой формы
ТекстСкрипта = "
|var element = document.getElementById('myInput');
|if (element) {
|    return element.value;
|}";
Элементы.ПолеHTML.ВыполнитьJavaScript(ТекстСкрипта);

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

Способ 2. Интеграция через протокол v8app

Если нам нужно не просто «читать» данные, а реагировать на события внутри HTML-поля (например, на двойной клик dblclick, как упоминалось в обсуждении), то лучшим способом будет использование механизма перехвата URL. Мы можем внедрить в HTML-код обработчик, который будет менять window.location, а 1С перехватит это событие.

Разберем по шагам, как это реализовать:

  1. Внутри HTML-страницы добавим JavaScript-функцию, которая будет отправлять данные в 1С.
  2. Используем специальный формат ссылки с протоколом v8app.
  3. В 1С создадим обработчик события ПриНажатии (или аналогичного для перехвата навигации).

Пример JavaScript кода внутри вашего HTML:


function sendTo1C(action, data) {
    window.location.href = "v8app://" + action + "/" + encodeURIComponent(data);
}

document.addEventListener('dblclick', function() {
    sendTo1C('double_click', 'User clicked the document');
});

В платформе 1С этот переход не вызовет открытия новой страницы, а будет интерпретирован как внешнее событие. Это позволяет обойти ограничения Same-Origin Policy, так как инициатором связи выступает «внутренняя» страница, а не «внешняя» база 1С.

Способ 3. Решение проблемы CORS при работе с AJAX

Рассмотрим ситуацию из сообщения №1: разработчик скачивает HTML программно и устанавливает его в поле через УстановитьТекст(). В этом случае страница считается открытой из источника about:blank или localhost. При попытке выполнить AJAX-запрос внутри такой страницы, браузер блокирует его из-за отсутствия заголовков CORS (Cross-Origin Resource Sharing).

Чтобы решить эту проблему, необходимо убедиться, что сервер, к которому обращается AJAX, отдает заголовок Access-Control-Allow-Origin: * (или указывает конкретный домен вашей публикации 1С). Без этого заголовка браузер в веб-клиенте никогда не позволит скрипту получить ответ от сервера.

Способ 4. Публикация на одном домене

Самый надежный, но архитектурно сложный способ заставить свойство Документ работать в веб-клиенте — это обеспечить совпадение доменов. Если ваша база 1С опубликована по адресу https://apps.mysite.ru/base, а HTML-ресурс доступен по адресу https://apps.mysite.ru/helper.html, то браузер посчитает их принадлежащими к одному источнику.

В такой ситуации ограничение SOP снимается, и вы сможете программно обращаться к Элементы.ПолеHTML.Документ точно так же, как в тонком клиенте. Если ресурсы находятся на разных серверах, можно использовать Reverse Proxy (например, Nginx), чтобы «склеить» их в один домен.

Подведем итоги

Мы выяснили, что отсутствие доступа к свойству Документ в веб-клиенте — это не баг платформы 1С, а стандартное поведение системы безопасности браузеров. Для эффективной работы рекомендуем следующее:

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

← На главную