При работе в веб-клиенте 1С:Предприятие разработчики и администраторы иногда сталкиваются с трудновоспроизводимыми ошибками JavaScript. Одной из наиболее коварных является ошибка «... is not a function» (или ее устаревший аналог «undefined is not a function»), возникающая в момент интерактивных действий пользователя — например, при нажатии кнопки «Записать и закрыть». Особенность этой проблемы в том, что она может проявляться бессистемно: лишь у некоторых пользователей и только для части документов.
В этой статье мы подробно разберем, почему возникает эта ошибка на уровне взаимодействия браузера и веб-сервера IIS, как правильно локализовать ее с помощью инструментов разработчика и какие шаги необходимо предпринять для ее окончательного устранения.
Для того чтобы понять природу этой ошибки, необходимо заглянуть под капот веб-клиента 1С. Когда пользователь запускает систему через браузер (например, Google Chrome), платформа компилирует программный код управляемых форм и клиентских модулей (директива &НаКлиенте) в динамические файлы JavaScript. Эти скрипты передаются веб-серверу (IIS или Apache) и исполняются непосредственно в браузере.
Сбой «is not a function» означает, что интерпретатор JavaScript на стороне браузера пытается вызвать метод у объекта, который в данный момент равен undefined, null или имеет другой тип данных, не поддерживающий этот метод. Рассмотрим основные причины этого явления:
mod_main_...js) обновляются на сервере. Однако браузер пользователя или кэш IIS могут продолжать использовать старые версии скриптов. В результате код пытается вызвать функцию по обфусцированному (сокращенному) имени, которого в новой версии сборки уже не существует.Предупреждение() или Вопрос(). Современные браузеры блокируют подобные вызовы, что приводит к критической ошибке JavaScript.Неопределено. При попытке обработать этот результат на клиенте JavaScript выдаст ошибку отсутствия функции.---
Поскольку ошибка возникает на клиенте, стандартный журнал регистрации 1С на сервере не зафиксирует подробности сбоя. Нам необходимо использовать встроенные инструменты разработчика в браузере Chrome.
Разберем алгоритм действий при возникновении ошибки:
Ctrl + Shift + I) для открытия панели разработчика Chrome DevTools.Uncaught TypeError: jfa.toUpperCase is not a function).mod_main_mainform.js) мы сможем определить, какое событие формы (ПередЗаписью, ПриЗаписи) или какой обработчик ожидания вызвал сбой.---
Для детального анализа поведения системы мы можем подключить отладчик 1С непосредственно к сессии веб-клиента. Проанализируем, как настроить отладку по шагам:
-debug -http.---
Рассмотрим подробнее четыре основных способа устранения этой ошибки, начиная от самых быстрых и заканчивая архитектурными исправлениями кода.
Как показывает практика, в подавляющем большинстве случаев возникновение несистемных ошибок JavaScript в веб-клиенте на платформе версий 8.3.13.х связано с внутренними багами самого движка платформы. Обновление платформы на актуальный стабильный релиз (например, из веток 8.3.18, 8.3.20 или выше) полностью устраняет проблему некорректной генерации JS-кода.
Если обновление платформы временно невозможно или не решило проблему, необходимо исключить фактор устаревшего кэша скриптов. Выполним следующие действия:
iisreset в командной строке от имени администратора.Ctrl + F5 для принудительного обновления страницы в обход кэша или очистим историю браузера за все время (раздел «Изображения и другие файлы, сохраненные в кэше»).Если ваша конфигурация содержит элементы старых систем (например, блоки из УТ 10.3), критически важно избавиться от синхронных модальных окон. Браузеры блокируют их, что мгновенно вызывает ошибку is not a function на клиенте.
Рассмотрим пример рефакторинга кода. Предположим, у нас использовался старый синхронный вызов вопроса перед записью:
// Устаревший синхронный код, вызывающий ошибку в веб-клиенте
Режим = РежимДиалогаВопрос.ДаНет;
Ответ = Вопрос("Вы действительно хотите записать документ?", Режим);
Если Ответ = КодВозвратаДиалога.Да Тогда
Записать();
КонецЕсли;
Мы должны переписать этот код с использованием асинхронного метода ПоказатьВопрос и описания оповещения:
// Современный асинхронный код, корректно работающий в браузере
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
// Если проверка уже пройдена, не задаем вопрос повторно
Если Не ДополнительныеСвойства.Свойство("ПроверкаПройдена") Тогда
Отказ = Истина; // Блокируем стандартную запись
Режим = РежимДиалогаВопрос.ДаНет;
Оповещение = Новый ОписаниеОповещения("ПослеВопросаОЗаписи", ЭтотОбъект, ПараметрыЗаписи);
ПоказатьВопрос(Оповещение, "Вы действительно хотите записать документ?", Режим);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПослеВопросаОЗаписи(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ДополнительныеСвойства.Вставить("ПроверкаПройдена", Истина);
// Повторно вызываем запись, которая теперь пройдет без вопросов
Записать(ДополнительныеПараметры);
КонецЕсли;
КонецПроцедуры
При интеграции с JIRA или другими системами по HTTP-протоколу сбой сети может вернуть пустой или некорректный ответ. Если этот ответ сразу передается на клиент без валидации, обращение к его свойствам на клиенте рухнет с ошибкой JavaScript.
Разберем пример безопасной обработки данных:
// НЕБЕЗОПАСНЫЙ ВАРЯНТ (может вызвать ошибку JavaScript на клиенте)
&НаКлиенте
Процедура ОбработатьОтветJira(ДанныеОтвета)
// Если ДанныеОтвета пришли как Неопределено, этот вызов вызовет "is not a function"
СтатусЗадачи = ДанныеОтвета.Получить("status");
КонецПроцедуры
// БЕЗОПАСНЫЙ ВАРИАНТ
&НаКлиенте
Процедура ОбработатьОтветJiraБезопасно(ДанныеОтвета)
// Проверяем тип пришедших данных перед обращением к методам
Если ДанныеОтвета = Неопределено Тогда
ПоказатьПредупреждение(, "Не удалось получить данные из JIRA. Проверьте подключение.");
Возврат;
КонецЕсли;
Если ТипЗнч(ДанныеОтвета) = Тип("Соответствие") Тогда
СтатусЗадачи = ДанныеОтвета.Получить("status");
Если СтатусЗадачи <> Неопределено Тогда
// Продолжаем логику обработки
КонецЕсли;
Иначе
ПоказатьПредупреждение(, "Получены данные неверного формата.");
КонецЕсли;
КонецПроцедуры
Применяя данные защитные механизмы в кодовой базе и своевременно обновляя платформу 1С:Предприятие, мы обеспечим стабильную и бесперебойную работу пользователей в режиме веб-клиента без раздражающих ошибок интерфейса.