Как организовать взаимодействие 1С с локальным API через JavaScript и решить проблему ожидания данных?

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

В современной разработке на платформе 1С:Предприятие часто возникает необходимость интеграции с внешними или локальными сервисами, которые предоставляют API. Одним из наиболее гибких способов является использование JavaScript внутри Поля HTML-документа. Однако разработчики часто сталкиваются с тем, что код 1С отрабатывает быстрее, чем загружается содержимое HTML или выполняются асинхронные запросы внутри браузерного движка. Разберем по шагам, как правильно настроить это взаимодействие, избегая типичных ошибок.

Анализ первой проблемы: Почему метод объекта не обнаружен?

Рассмотрим ситуацию, когда мы пытаемся вызвать JavaScript-функцию напрямую из 1С сразу после установки текста HTML. Часто код выглядит следующим образом:


функцияА =" |function connect() { | alert('Соединение...'); |}"; 
ШаблонHTML = "<html><script>" + функцияА + "</script></html>"; 
Объект.хтмл = ШаблонHTML; 
ОкноДокумента = Элементы.хтмл.Документ.defaultView; 
Результат = ОкноДокумента.connect(); // Здесь часто возникает ошибка

Проанализируем причину неудачи. Когда мы присваиваем строку переменной, связанной с полем HTML-документа, платформа начинает процесс рендеринга страницы. Этот процесс происходит асинхронно по отношению к коду на языке 1С. В момент выполнения строки с вызовом функции connect(), DOM-дерево еще не построено, и скрипт не инициализирован. Именно поэтому система выдает ошибку "Метод объекта не обнаружен".

Решение 1: Использование события ДокументСформирован

Чтобы гарантировать наличие доступа к методам JavaScript, мы должны дождаться полной загрузки страницы. Для этого в управляемых формах предусмотрено специализированное событие ПриСформировании (или ДокументСформирован в зависимости от версии платформы и типа элемента).

Рассмотрим правильный алгоритм действий:

  1. Установим текст HTML в реквизит.
  2. Дождемся срабатывания обработчика события ПолеHTMLДокументСформирован.
  3. Только внутри этого обработчика будем обращаться к defaultView.

Пример кода в модуле формы:


&НаКлиенте
Процедура ПолеHTMLДокументСформирован(Элемент)
    // Получаем окно документа
    ОкноHTML = Элементы.ПолеHTML.Документ.defaultView;
    
    Если ОкноHTML = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Теперь метод точно будет доступен
    Попытка
        Ответ = ОкноHTML.connect();
    Исключение
        Сообщить("Ошибка вызова JS: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Решение 2: Проблема асинхронности в самом JavaScript (Delays)

Выясним причину второй популярной проблемы: когда JS-код содержит задержки (например, запросы к API через fetch или setTimeout), и 1С получает пустое значение. В этом случае документ уже сформирован, но сами данные внутри JS еще не получены.

Если ваша JS-функция обращается к локальному API, она делает это асинхронно. Программа 1С не будет ждать завершения внутреннего процесса в браузере, она просто выполнит вызов функции и пойдет дальше. Чтобы решить эту задачу, нам нужно изменить архитектуру: не 1С должна "тянуть" данные, а JavaScript должен сообщить 1С, когда данные будут готовы.

Для этого в современных версиях платформы (8.3.14+) рекомендуется использовать метод ВыполнитьJavaScript с механизмом оповещения.


&НаКлиенте
Процедура ВызватьAPI(Команда)
    ОписаниеОповещения = Новый ОписаниеОповещения("ЗавершениеВыполненияJS", ЭтаФорма);
    // Вызываем JS функцию, которая вернет Promise или результат позже
    Элементы.ПолеHTML.ВыполнитьJavaScript(ОписаниеОповещения, "getDataFromLocalAPI()");
КонецПроцедуры

&НаКлиенте
Процедура ЗавершениеВыполненияJS(Результат, ДополнительныеПараметры) Экспорт
    Если Результат <> Неопределено Тогда
        Сообщить("Данные получены: " + Результат);
    КонецЕсли;
КонецПроцедуры

Решение 3: Обратная связь через внешние события

Разберем ситуацию, когда JS-код работает долго (например, ожидает ответа от оборудования через локальный API). В этом случае удобно использовать механизм внешних событий. JavaScript может инициировать событие, которое 1С перехватит в обработчике ВнешнееСобытие.

В коде JavaScript (если используется движок Chromium) это может выглядеть так:


function sendDataTo1C(data) {
    // В зависимости от версии платформы и настроек
    // можно использовать изменение заголовка или специальные объекты
    window.external.MessageFromJS("DataReady", JSON.stringify(data));
}

В 1С это позволит избежать "зависания" интерфейса и бесконечных циклов ожидания.

Важные технические нюансы

Проанализируем дополнительные факторы, влияющие на стабильность работы:

Альтернативный подход: Прямое использование HTTPСоединение

Выясним, всегда ли нужен JavaScript для работы с локальным API. Если ваша задача — просто отправить GET или POST запрос и получить JSON, использование Поля HTML-документа является избыточным и сложным в поддержке. Платформа 1С обладает мощным встроенным объектом HTTPСоединение.

Посмотрим на пример прямого обращения к локальному API из 1С:


Соединение = Новый HTTPСоединение("localhost", 8080);
Запрос = Новый HTTPЗапрос("/api/method");
Попытка
    Ответ = Соединение.Получить(Запрос);
    Если Ответ.КодСостояния = 200 Тогда
        Данные = Ответ.ПолучитьТелоКакСтроку();
        // Далее работаем с JSON через ЧтениеJSON
    КонецЕсли;
Исключение
    Сообщить("Ошибка связи: " + ОписаниеОшибки());
КонецПопытки;

Резюме: Если API не требует специфических браузерных функций (например, работы с криптографическими плагинами или сложной визуализации), используйте HTTPСоединение. Если же работа через JavaScript неизбежна, всегда используйте событие ДокументСформирован и метод ВыполнитьJavaScript для обеспечения надежного обмена данными.

← На главную