В современной разработке на платформе 1С:Предприятие часто возникает необходимость интеграции с внешними или локальными сервисами, которые предоставляют API. Одним из наиболее гибких способов является использование JavaScript внутри Поля HTML-документа. Однако разработчики часто сталкиваются с тем, что код 1С отрабатывает быстрее, чем загружается содержимое HTML или выполняются асинхронные запросы внутри браузерного движка. Разберем по шагам, как правильно настроить это взаимодействие, избегая типичных ошибок.
Рассмотрим ситуацию, когда мы пытаемся вызвать JavaScript-функцию напрямую из 1С сразу после установки текста HTML. Часто код выглядит следующим образом:
функцияА =" |function connect() { | alert('Соединение...'); |}";
ШаблонHTML = "<html><script>" + функцияА + "</script></html>";
Объект.хтмл = ШаблонHTML;
ОкноДокумента = Элементы.хтмл.Документ.defaultView;
Результат = ОкноДокумента.connect(); // Здесь часто возникает ошибка
Проанализируем причину неудачи. Когда мы присваиваем строку переменной, связанной с полем HTML-документа, платформа начинает процесс рендеринга страницы. Этот процесс происходит асинхронно по отношению к коду на языке 1С. В момент выполнения строки с вызовом функции connect(), DOM-дерево еще не построено, и скрипт не инициализирован. Именно поэтому система выдает ошибку "Метод объекта не обнаружен".
Чтобы гарантировать наличие доступа к методам JavaScript, мы должны дождаться полной загрузки страницы. Для этого в управляемых формах предусмотрено специализированное событие ПриСформировании (или ДокументСформирован в зависимости от версии платформы и типа элемента).
Рассмотрим правильный алгоритм действий:
ПолеHTMLДокументСформирован.defaultView.Пример кода в модуле формы:
&НаКлиенте
Процедура ПолеHTMLДокументСформирован(Элемент)
// Получаем окно документа
ОкноHTML = Элементы.ПолеHTML.Документ.defaultView;
Если ОкноHTML = Неопределено Тогда
Возврат;
КонецЕсли;
// Теперь метод точно будет доступен
Попытка
Ответ = ОкноHTML.connect();
Исключение
Сообщить("Ошибка вызова JS: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Выясним причину второй популярной проблемы: когда JS-код содержит задержки (например, запросы к API через fetch или setTimeout), и 1С получает пустое значение. В этом случае документ уже сформирован, но сами данные внутри JS еще не получены.
Если ваша JS-функция обращается к локальному API, она делает это асинхронно. Программа 1С не будет ждать завершения внутреннего процесса в браузере, она просто выполнит вызов функции и пойдет дальше. Чтобы решить эту задачу, нам нужно изменить архитектуру: не 1С должна "тянуть" данные, а JavaScript должен сообщить 1С, когда данные будут готовы.
Для этого в современных версиях платформы (8.3.14+) рекомендуется использовать метод ВыполнитьJavaScript с механизмом оповещения.
&НаКлиенте
Процедура ВызватьAPI(Команда)
ОписаниеОповещения = Новый ОписаниеОповещения("ЗавершениеВыполненияJS", ЭтаФорма);
// Вызываем JS функцию, которая вернет Promise или результат позже
Элементы.ПолеHTML.ВыполнитьJavaScript(ОписаниеОповещения, "getDataFromLocalAPI()");
КонецПроцедуры
&НаКлиенте
Процедура ЗавершениеВыполненияJS(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
Сообщить("Данные получены: " + Результат);
КонецЕсли;
КонецПроцедуры
Разберем ситуацию, когда JS-код работает долго (например, ожидает ответа от оборудования через локальный API). В этом случае удобно использовать механизм внешних событий. JavaScript может инициировать событие, которое 1С перехватит в обработчике ВнешнееСобытие.
В коде JavaScript (если используется движок Chromium) это может выглядеть так:
function sendDataTo1C(data) {
// В зависимости от версии платформы и настроек
// можно использовать изменение заголовка или специальные объекты
window.external.MessageFromJS("DataReady", JSON.stringify(data));
}
В 1С это позволит избежать "зависания" интерфейса и бесконечных циклов ожидания.
Проанализируем дополнительные факторы, влияющие на стабильность работы:
defer в теге <script> работает только для внешних файлов (с атрибутом src). Для встроенных скриптов он игнорируется.localhost:8080, браузер внутри 1С может заблокировать запрос. Убедитесь, что ваш локальный API возвращает заголовок Access-Control-Allow-Origin: *.Выясним, всегда ли нужен JavaScript для работы с локальным API. Если ваша задача — просто отправить GET или POST запрос и получить JSON, использование Поля HTML-документа является избыточным и сложным в поддержке. Платформа 1С обладает мощным встроенным объектом HTTPСоединение.
Посмотрим на пример прямого обращения к локальному API из 1С:
Соединение = Новый HTTPСоединение("localhost", 8080);
Запрос = Новый HTTPЗапрос("/api/method");
Попытка
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
Данные = Ответ.ПолучитьТелоКакСтроку();
// Далее работаем с JSON через ЧтениеJSON
КонецЕсли;
Исключение
Сообщить("Ошибка связи: " + ОписаниеОшибки());
КонецПопытки;
Резюме: Если API не требует специфических браузерных функций (например, работы с криптографическими плагинами или сложной визуализации), используйте HTTPСоединение. Если же работа через JavaScript неизбежна, всегда используйте событие ДокументСформирован и метод ВыполнитьJavaScript для обеспечения надежного обмена данными.