При интеграции сторонних веб-сервисов в интерфейс 1С через ПолеHTMLдокумента разработчики часто сталкиваются с тем, что стандартные методы платформы ведут себя не так, как ожидается. Основные сложности возникают при попытке программно взаимодействовать с элементами форм (кнопками, переключателями) и при необходимости перемещаться по страницам сайта без потери текущей авторизации. В данной статье мы подробно разберем, как правильно эмулировать действия пользователя и управлять сессиями в движках WebKit и Chromium, используемых в 1С.
Рассмотрим ситуацию: на веб-странице есть радио-кнопка, которую необходимо выбрать программно из кода 1С. Часто программисты пытаются решить задачу «в лоб», напрямую обращаясь к объекту DOM и меняя его свойство checked или status. Однако, если на сайте используются современные фреймворки (React, Angular, Vue) или просто навешены обработчики событий JavaScript, такое изменение состояния останется незамеченным для внутренней логики сайта. Валидация формы не пройдет, так как событие изменения не было инициировано.
Проанализируем правильный подход. Чтобы сайт «понял», что кнопка нажата, недостаточно просто изменить флаг. Необходимо вызвать соответствующее событие (Event). В старых версиях (Internet Explorer) это делалось через fireEvent, но в WebKit и Chromium следует использовать механизм dispatchEvent. Разберем по шагам, как это реализовать в 1С:
// Находим элемент по идентификатору
Элемент = ЭлементыФормы.ПолеHTML.Документ.getElementById("ctl00_CCAuth1_userSelectRadioList_0");
// Устанавливаем состояние
Элемент.checked = Истина;
// Инициируем событие изменения, чтобы сработали скрипты валидации на сайте
Элемент.dispatchEvent(ЭлементыФормы.ПолеHTML.Документ.createEvent("HTMLEvents"));
// Для современных движков лучше использовать dispatchEvent с новым объектом Event
Если прямое обращение через модель COM работает нестабильно, рекомендуется использовать впрыск (инъекцию) JavaScript-кода. Рассмотрим пример универсальной функции, которую можно вызвать для клика по любому элементу:
Процедура НажатьЭлементПрограммно(Идентификатор)
ТекстJS = "
|var el = document.getElementById('" + Идентификатор + "');
|if (el) {
| el.checked = true;
| var event = new Event('change', { bubbles: true });
| el.dispatchEvent(event);
| el.click();
|}";
// Выполняем скрипт в контексте загруженной страницы
ЭлементыФормы.ПолеHTML.Документ.parentWindow.eval(ТекстJS);
КонецПроцедуры
Следующая серьезная проблема — потеря сессии. Выясним причину: когда мы используем встроенный метод платформы Перейти() (или Navigate()), 1С может инициировать новый сеанс браузера или выполнять запрос без передачи накопленных в заголовках данных Cookies. В результате пользователь, успешно прошедший авторизацию, при программном переходе на следующую страницу внезапно оказывается «неавторизованным».
Чтобы избежать этой ситуации, мы должны заставить сам движок браузера выполнить переход внутри текущего контекста. Рассмотрим, как заменить стандартный метод Перейти() на использование объекта location. Проанализируем пример кода:
// Вместо этого:
// ЭлементыФормы.ПолеHTML.Перейти("https://mysite.ru/profile");
// Используем этот способ для сохранения кук:
Документ = ЭлементыФормы.ПолеHTML.Документ;
Документ.defaultView.location.href = "https://mysite.ru/profile";
Этот метод заставляет WebKit выполнить навигацию так, как если бы пользователь сам кликнул по ссылке. В этом случае все заголовки и куки сессии гарантированно передаются серверу. Если на странице есть ссылка с определенным классом, можно также программно вызвать метод click() на самой ссылке (объекте <a>).
Часто возникает задача не просто просматривать страницы, но и скачивать файлы (отчеты, документы), которые доступны только авторизованным пользователям. При нажатии на кнопку «Скачать» в ПолеHTMLдокумента 1С обычно открывает стандартное системное диалоговое окно сохранения файла, которое невозможно автоматизировать штатными средствами.
Рассмотрим стратегию автоматического скачивания:
HTTPСоединение и подставляем полученные куки в заголовки запроса.GET-запрос к URL файла.Посмотрим на пример реализации получения кук для последующей передачи в HTTPЗапрос:
// Получаем строку кук из документа
СтрокаКук = ЭлементыФормы.ПолеHTML.Документ.cookie;
// Далее используем их в HTTPЗапросе
ЗаголовокЗапроса = Новый Соответствие;
ЗаголовокЗапроса.Вставить("Cookie", СтрокаКук);
Соединение = Новый HTTPСоединение("mysite.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос("/files/report.pdf", ЗаголовокЗапроса);
Результат = Соединение.Получить(Запрос, "C:\Temp\report.pdf");
Этот метод позволяет полностью автоматизировать процесс работы с сайтом: от входа под логином и паролем до получения конечного файла в конкретную директорию на диске без участия пользователя.
Разберем важный нюанс: начиная с версии платформы 8.3.14, 1С перешла на использование Chromium Embedded Framework (CEF) вместо устаревшего WebKit. Это расширило возможности разработчиков, но и изменило некоторые принципы работы.
Для отладки сложных скриптов внутри 1С полезно знать о возможности включения удаленной отладки. Если запустить клиент 1С с параметром командной строки --remote-debugging-port=9222, вы сможете подключиться к форме 1С из обычного браузера Chrome, введя в адресную строку localhost:9222. Это откроет полноценную консоль разработчика (DevTools), где можно проинспектировать DOM, увидеть ошибки в консоли и проанализировать сетевые запросы (вкладка Network), что значительно упрощает поиск причин «слетающей» авторизации.
Важный совет: При работе в Толстом клиенте (Обычные формы) всегда проверяйте, какой движок используется. Если в системе принудительно включен режим совместимости с Internet Explorer, многие методы JavaScript из стандарта ES6 могут не поддерживаться, и вам придется использовать более старый синтаксис (например, var вместо let и отказ от стрелочных функций).