Интеграция веб-технологий в решения на базе платформы 1С — задача весьма популярная. Разработчики часто используют поле HTML-документа для отображения интерактивных карт (например, Google Maps или Яндекс.Карты), графиков, диаграмм или сложных веб-интерфейсов. Однако при обновлении операционной системы, браузера Internet Explorer или самой платформы 1С старые, годами работавшие механизмы взаимодействия между JavaScript (JS) и кодом 1С (BSL) могут внезапно выйти из строя.
В этой статье мы подробно разберем, почему перестает работать популярное событие ondatasetcomplete, как быстро вернуть работоспособность старому коду и как правильно переписать взаимодействие между 1С и JS по современным кроссплатформенным стандартам, которые гарантированно будут работать на любых версиях платформы 1С.
Раньше в операционной системе Windows для рендеринга содержимого поля HTML-документа платформа 1С использовала встроенный движок MSHTML (Internet Explorer). Для передачи данных из JavaScript обратно в форму 1С разработчики часто использовали специфические для IE методы генерации событий. Код в JS выглядел следующим образом:
var evt = document.createEventObject();
document.body.fireEvent('ondatasetcomplete', evt);
В самой 1С на стороне формы существовал предопределенный обработчик события поля HTML-документа с именем ondatasetcomplete() (в русскоязычной локализации — Эксплорерondatasetcomplete()), который успешно перехватывал это событие и позволял прочитать переданные данные.
Начиная с версии Internet Explorer 11 (и даже в некоторых режимах IE10), Microsoft объявила проприетарные методы document.createEventObject() и fireEvent() устаревшими (deprecated) и полностью удалила их поддержку в угоду стандартам W3C. Попытка переписать код на стандартный веб-интерфейс создания событий тоже часто терпит неудачу:
var evt = document.createEvent("HTMLEvents");
evt.initEvent('ondatasetcomplete', true, true);
// Событие создается, но 1С его больше не видит!
Ситуация усложняется тем, что начиная с версии платформы 1С 8.3.14, фирма «1С» полностью отказалась от использования Internet Explorer в пользу кроссплатформенного движка WebKit (Chromium). В этом новом окружении любые специфические вызовы, ориентированные на IE, принципиально не работают, а объектная модель COM-соединения с формой полностью отсутствует.
Если ваша конфигурация работает на обычных формах, используется старая версия платформы (ниже 8.3.14), а пользователи работают на компьютерах с установленным Internet Explorer, вы можете быстро вернуть работоспособность старому коду. Для этого необходимо принудительно заставить движок рендеринга использовать режим совместимости с IE10 или IE9.
Разберем по шагам, как это сделать. Вам нужно добавить специальный мета-тег в заголовок <head> вашего HTML-документа:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=10" />
<title>Интеграция с картой</title>
</head>
<body>
<!-- Ваш HTML-код -->
</body>
</html>
Этот тег указывает браузеру эмулировать стандарты и поведение JavaScript-движка версии IE10. После этого старый код инициализации события через document.createEventObject() снова начнет функционировать. Однако помните: это временное решение. При обновлении платформы до актуальных релизов этот код окончательно перестанет работать, поэтому крайне рекомендуется перейти на современный стандарт.
Для того чтобы ваше решение работало стабильно как в обычных, так и в управляемых формах, а также на новых версиях платформы 1С с движком WebKit, необходимо полностью отказаться от привязки к событию ondatasetcomplete. Вместо этого мы применим стандартный и универсальный механизм перехвата кликов через событие «ПриНажатии» (в JS — onclick).
Суть метода заключается в создании скрытого элемента-моста на HTML-странице. Когда JS-коду требуется передать данные в 1С, он записывает эти данные в атрибуты скрытого элемента и программно имитирует клик по нему. 1С перехватывает это нажатие, считывает данные и отменяет стандартный переход по ссылке.
Рассмотрим детально реализацию этого механизма.
Шаг 1. Создание скрытого элемента в HTML-коде
Добавим в тело HTML-документа невидимую ссылку. Для передачи сложных структур данных будем использовать пользовательские атрибуты спецификации HTML5 (семейство data-*):
<a id="1c-bridge" style="display:none;" data-event="" data-payload=""></a>
Шаг 2. Реализация функции отправки данных на стороне JavaScript
Напишем универсальную функцию в JS, которая будет упаковывать переданные объекты в формат JSON и инициировать событие клика:
function sendDataTo1C(eventName, dataObject) {
var bridge = document.getElementById('1c-bridge');
if (bridge) {
// Записываем имя события и сериализуем данные в JSON-строку
bridge.setAttribute('data-event', eventName);
bridge.setAttribute('data-payload', JSON.stringify(dataObject));
// Симулируем клик мышкой для перехвата в 1С
bridge.click();
}
}
// Пример вызова при получении координат от Google Maps:
var coordinates = { lat: 55.7558, lng: 37.6173 };
sendDataTo1C('MapCoordinates', coordinates);
Шаг 3. Обработка события в коде 1С (BSL)
В модуле формы 1С для элемента управления «Поле HTML-документа» назначим обработчик события ПриНажатии (или onclick). Код обработчика будет выглядеть следующим образом:
&НаКлиенте
Процедура ПолеHTMLПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
// Проверяем, что событие произошло именно на нашем скрытом элементе-мосте
Если ДанныеСобытия.Anchor <> Неопределено Тогда
Атрибуты = ДанныеСобытия.Anchor.attributes;
Попытка
ИмяСобытия = Атрибуты.getNamedItem("data-event").value;
СтрокаДанных = Атрибуты.getNamedItem("data-payload").value;
Исключение
// Кликнули по другой ссылке, не относящейся к нашему мосту
Возврат;
КонецПопытки;
Если ИмяСобытия = "MapCoordinates" Тогда
// Блокируем стандартную реакцию браузера на клик
СтандартнаяОбработка = Ложь;
// Обрабатываем полученные данные
РазберемПолученныеКоординаты(СтрокаДанных);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура РазберемПолученныеКоординаты(Знач СтрокаJSON)
// Используем встроенные средства платформы для десериализации JSON
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
ДанныеКоординат = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Теперь у нас есть структура 1С с полями lat и lng
Широта = ДанныеКоординат.lat;
Долгота = ДанныеКоординат.lng;
ПоказатьПредупреждение(, "Получены координаты из JS: Широта " + Широта + ", Долгота " + Долгота);
КонецПроцедуры
Помимо передачи данных из JS в 1С, часто требуется и обратное действие — вызвать JS-функцию из кода модуля 1С. В старых решениях, ориентированных на Internet Explorer, разработчики использовали обращение через parentWindow:
// Этот код БОЛЬШЕ НЕ РАБОТАЕТ в WebKit
Элементы.ПолеHTML.Документ.parentWindow.myFunction(Параметр);
В современных версиях платформы на базе WebKit/Chromium объект parentWindow не поддерживается. Для вызова глобальных функций JavaScript необходимо использовать стандартное свойство defaultView:
// Современный кроссплатформенный вызов JS-функции из 1С
ДокументHTML = Элементы.ПолеHTML.Документ;
Если ДокументHTML <> Неопределено Тогда
ДокументHTML.defaultView.myFunction(Параметр1, Параметр2);
КонецЕсли;
Обратите внимание на важный нюанс: при передаче параметров из 1С в JavaScript старайтесь использовать только простые типы данных (числа, строки, булево). Если вам необходимо передать сложный объект (например, ТаблицуЗначений или Структуру), обязательно предварительно сериализуйте его в JSON-строку на стороне 1С с помощью объекта ЗаписьJSON, а на стороне JS преобразуйте обратно через JSON.parse(). Это убережет вас от ошибок несовместимости типов в разных браузерных движках.
Если вы планируете развивать интеграцию и строить сложные интерфейсы на базе современных JS-фреймворков (React, Vue, Svelte), учитывайте особенности встроенного в 1С движка WebKit:
<style> и <script>, а картинки переведены в формат Base64). Такой файл легко хранить в конфигурации 1С в качестве макета двоичных данных и загружать в поле HTML-документа одной строкой.Применение предложенного кроссплатформенного шаблона на базе скрытого элемента-моста и свойства defaultView позволит вам полностью избавиться от устаревших технологий Microsoft и гарантирует стабильную работу ваших интеграционных решений на любых современных релизах платформы 1С.