В современной разработке на платформе 1С:Предприятие 8.3 часто возникает необходимость интеграции с веб-сервисами: картами, графиками или сложными интерфейсными решениями. Основным инструментом для этого служит ПолеHTMLДокумента. Однако программисты часто сталкиваются с проблемой: как передать данные из кода 1С в JavaScript-окружение и корректно вызвать функции, определенные внутри HTML-страницы. В этой статье мы подробно разберем, как наладить это взаимодействие, решим проблему передачи массивов и разберемся с особенностями новых движков отображения HTML.
Прежде чем переходить к коду, проанализируем ситуацию, когда 1С выдает ошибку при попытке вызова функции. Чаще всего это происходит по двум причинам:
ПриСозданииНаСервере или слишком рано на клиенте, когда DOM-дерево страницы еще не загружено, и скрипты не инициализированы.parentWindow. В новых версиях (начиная с 8.3.14) используется WebKit/Chromium, где структура обращения изменилась.myFunction, обращение из 1С должно быть точно таким же.Рассмотрим наиболее актуальный способ для последних релизов платформы 1С. Вместо устаревшего parentWindow мы будем использовать свойство defaultView. Это позволяет обращаться к глобальной области видимости окна браузера напрямую.
Для начала создадим простейшую HTML-страницу с функцией, которую мы будем вызывать. Мы можем хранить этот текст в макете или формировать программно:
<html>
<head>
<script>
function ShowMessage(text) {
alert("Сообщение из 1С: " + text);
return true;
}
</script>
</head>
<body>
<h1>Интерактивная страница</h1>
</body>
</html>
Теперь разберем, как правильно вызвать эту функцию со стороны 1С. Важно дождаться события ДокументСформирован, чтобы гарантировать наличие функции в памяти браузера.
&НаКлиенте
Перем ДокументГотов;
&НаКлиенте
Процедура ПолеHTMLДокументСформирован(Элемент)
ДокументГотов = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ВызватьJSФункцию(Команда)
Если Не ДокументГотов Тогда
Возврат;
КонецЕсли;
// Получаем окно документа
ОкноJS = Элементы.ПолеHTML.Документ.defaultView;
// Вызываем функцию напрямую
Попытка
ОкноJS.ShowMessage("Привет из 1С!");
Исключение
Сообщить("Не удалось вызвать функцию: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Одной из главных проблем, обсуждаемых программистами, является передача массивов. Напрямую передать объект Массив из 1С в JavaScript не всегда получается корректно из-за разницы типов данных COM и JS. Проанализируем два способа решения этой задачи.
Вариант А: Использование метода Eval. Мы можем заставить JavaScript самостоятельно сконструировать массив из строки, которую мы подготовим в 1С. Это избавляет от проблем несовместимости типов.
&НаКлиенте
Процедура ПередатьМассивЧерезEval()
// Формируем строку массива для JS
СтрокаМассива = "[10, 20, 30, 40]";
Элементы.ПолеHTML.Документ.defaultView.eval("ProcessArray(" + СтрокаМассива + ")");
КонецПроцедуры
Вариант Б: Использование JSON (Рекомендуемый). Это самый надежный и современный способ. Мы преобразуем массив или структуру 1С в строку JSON, передаем ее как один строковый параметр, а в JavaScript декодируем обратно в объект.
В 1С (код):
&НаКлиенте
Процедура ПередатьДанныеJSON()
Данные = Новый Массив;
Данные.Добавить("Параметр 1");
Данные.Добавить(123);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Данные);
СтрокаJSON = ЗаписьJSON.Закрыть();
// Вызываем функцию, передавая JSON-строку
Элементы.ПолеHTML.Документ.defaultView.DataHandler(СтрокаJSON);
КонецПроцедуры
В JavaScript (код на странице):
function DataHandler(jsonString) {
var data = JSON.parse(jsonString);
console.log(data[0]); // Выведет "Параметр 1"
console.log(data[1]); // Выведет 123
}
Если ваше приложение работает в веб-клиенте, прямой доступ к Элементы.ПолеHTML.Документ может быть закрыт из-за политики безопасности браузеров (Cross-Origin). В этом случае выясним, как обойти ограничение.
Рассмотрим механизм взаимодействия через навигацию. Вы можете изменить текст в поле HTML-документа или использовать событие ПриНажатии. Однако для вызова JS из 1С в веб-клиенте часто применяется методика «инъекции» кода через изменение реквизита, к которому привязан HTML-текст, но это требует перезагрузки страницы.
Для полноценного взаимодействия в веб-клиенте рекомендуется использовать библиотеку window.postMessage, если страница загружается с другого домена, или встраивать логику обработки событий в саму страницу, чтобы 1С лишь меняла данные, а скрипт JS реагировал на их изменение через MutationObserver.
Проанализируем несколько важных моментов, которые помогут избежать ошибок при эксплуатации решения:
defaultView.ИмяФункции в 1С и function ИмяФункции в JS совпадают до символа.ДокументСформирован.Попытка ... Исключение. Это позволит программе не «падать», если пользователь закроет форму в момент выполнения скрипта или если возникнет ошибка внутри самого JavaScript.JSON.parse) могут быть недоступны:
<meta http-equiv="X-UA-Compatible" content="IE=edge" />Используя предложенные подходы, мы можем организовать бесшовную интеграцию между бизнес-логикой 1С и интерактивными возможностями современных веб-технологий, обеспечивая высокую скорость работы и удобство интерфейса для конечного пользователя.