Как исправить ошибку «Использование модальных окон в данном режиме запрещено!» при работе с файлами в веб-клиенте 1С

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

Каждый разработчик 1С рано или поздно сталкивается с ситуацией, когда код, безупречно работающий в тонком или толстом клиенте, внезапно отказывается функционировать в веб-клиенте. Одной из наиболее распространенных проблем является возникновение ошибки «Использование модальных окон в данном режиме запрещено!» при попытке загрузить или обработать локальный файл пользователя.

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

Почему возникает ошибка: ограничения веб-клиента

Для того чтобы понять природу проблемы, нам необходимо обратиться к архитектуре современных веб-браузеров. В отличие от настольного приложения (тонкого клиента), веб-клиент 1С выполняется внутри браузера в изолированной среде — так называемой «песочнице». Это накладывает жесткие ограничения на безопасность:

  1. Браузер принципиально не имеет прямого синхронного доступа к локальной файловой системе пользователя. Любая попытка прочитать файл «на лету» без явного разрешения пользователя приводит к блокировке операции.
  2. Современные веб-стандарты полностью отказались от поддержки синхронных модальных окон (таких как устаревший метод showModalDialog), поскольку они полностью замораживают интерфейс браузера, ухудшая пользовательский опыт и создавая угрозы безопасности.

Начиная с версии платформы 8.3.10, в веб-клиенте 1С полностью прекращена поддержка модальных окон, независимо от того, какое значение установлено в свойствах конфигурации для параметра Режим использования модальности. Даже если там указано «Разрешить», веб-клиент проигнорирует эту настройку и выбросит исключение при первой же попытке открыть модальный диалог или выполнить блокирующую синхронную операцию.

Анализ исходного кода и скрытые баги

Давайте подробно проанализируем фрагмент кода, который вызвал затруднения у автора темы на форуме. Проблема скрывается внутри процедуры-обработчика оповещения:


&НаКлиенте
Процедура ОбработатьВыборФайла(ПомещенныеФайлы, ДополнительныеПараметры) Экспорт
    Если ПомещенныеФайлы = Неопределено Тогда
        Возврат;
    КонецЕсли;
    Для каждого ПереданныйФайл Из ПомещенныеФайлы Цикл
        ПутьКФайлу = ПереданныйФайл.Имя;
        Адрес = ПереданныйФайл.Хранение;
        Объект.ФайлНаЛокальномПК=ПереданныйФайл.Имя;
        ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу); // <-- ИСТОЧНИК КРИТИЧЕСКОЙ ОШИБКИ
        ИмяФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные );
    КонецЦикла;
    СоздатьСсылкуНаСервере(ИмяФайла);
КонецПроцедуры

В этом коде содержатся сразу три серьезные ошибки, которые делают его неработоспособным в веб-клиенте:

  1. Попытка синхронного чтения диска: Строка ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу) выполняется на стороне клиента. Конструктор Новый ДвоичныеДанные пытается выполнить синхронное чтение файла с локального диска компьютера. В веб-клиенте это немедленно вызывает блокировку со стороны безопасности браузера, что и приводит к ошибке запрета модальных/синхронных вызовов.
  2. Отсутствие полного пути к файлу: Начиная с версии платформы 8.3.14, в целях обеспечения безопасности личных данных пользователей, свойство Имя объекта ОписаниеПереданногоФайла (или ПереданныйФайл) в веб-клиенте содержит только краткое имя файла (например, report.xlsx), а не полный путь на диске (вроде C:\Users\Username\Documents\report.xlsx). Таким образом, даже в тонком клиенте попытка вызвать Новый ДвоичныеДанные("report.xlsx") без указания полного пути приведет к ошибке «Файл не найден».
  3. Абсолютная избыточность кода: Это самый важный технологический момент. Метод НачатьПомещениеФайлов спроектирован так, что он уже самостоятельно загружает выбранные пользователем файлы во временное хранилище на сервере 1С. Готовый уникальный адрес этого хранилища возвращается в свойстве ПереданныйФайл.Хранение. Повторно читать файл с локального диска, создавать двоичные данные и снова помещать их в хранилище через метод ПоместитьВоВременноеХранилище нет абсолютно никакой необходимости!

Пошаговое исправление кода

Для того чтобы исправить ошибку, нам нужно полностью убрать повторное чтение файла на клиенте. Мы должны сразу использовать готовый адрес временного хранилища, который платформа нам предоставила. Изменим процедуру-обработчик следующим образом:


&НаКлиенте
Процедура ОбработатьВыборФайла(ПомещенныеФайлы, ДополнительныеПараметры) Экспорт
    Если ПомещенныеФайлы = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Для каждого ПереданныйФайл Из ПомещенныеФайлы Цикл
        // Записываем имя файла для отображения в интерфейсе
        Объект.ФайлНаЛокальномПК = ПереданныйФайл.Имя; 
        
        // Передаем на сервер готовый адрес во временном хранилище
        СоздатьСсылкуНаСервере(ПереданныйФайл.Хранение); 
    КонецЦикла;
КонецПроцедуры

Посмотрим, насколько упростился код! Теперь клиентская процедура работает молниеносно, не совершает запрещенных синхронных обращений к диску и не вызывает никаких модальных окон в веб-клиенте.

На стороне сервера (в процедуре СоздатьСсылкуНаСервере) мы можем спокойно работать с полученным адресом временного хранилища:


&НаСервере
Процедура СоздатьСсылкуНаСервере(АдресВХ)
    // Здесь мы можем получить двоичные данные файла на стороне сервера абсолютно безопасно
    ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресВХ);
    
    // Выполняем необходимую бизнес-логику (сохранение в базу данных, обработка и т.д.)
    // ...
КонецПроцедуры

Режим использования синхронных вызовов

Помимо настройки модальности, в свойствах конфигурации существует крайне важный параметр — Режим использования синхронных вызовов расширений платформы и внешних компонент. В современных конфигурациях 1С (особенно построенных на базе БСП последних версий) этот параметр по умолчанию установлен в значение «Не использовать».

При таком режиме работы любые синхронные методы работы с файловой системой (например, использование объекта Файл, проверка существования файлов через синхронные методы и т.д.) будут приводить к аварийному завершению работы в веб-клиенте. Платформа требует строгого разделения кода на интерактивный асинхронный (на клиенте) и исполняемый (на сервере).

Нужна ли установка расширения работы с файлами в браузере?

В процессе обсуждения на форуме участники затронули тему использования расширения работы с файлами в веб-клиенте. Давайте проясним эту ситуацию:

Современный стандарт асинхронной разработки (Платформа 8.3.15 и выше)

Развитие платформы 1С привело к тому, что старые методы НачатьПомещениеФайла() и НачатьПомещениеФайлов() были признаны устаревшими и не рекомендуются к использованию. Вместо них разработчикам следует использовать современные асинхронные аналоги, которые обеспечивают максимальную совместимость с мобильным клиентом и веб-клиентом под любыми операционными системами.

Давайте рассмотрим пример написания современного, кодобезопасного механизма для выбора и помещения файлов на сервер с использованием метода НачатьПомещениеФайловНаСервер():


&НаКлиенте
Процедура НачатьЗагрузкуФайла()
    
    // Создаем описание оповещения, указывая процедуру завершения
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеПомещенияФайлов", ЭтаФорма);
    
    // Настраиваем параметры диалога выбора файлов
    ПараметрыДиалога = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ПараметрыДиалога.Заголовок = "Выберите файл для загрузки в систему";
    ПараметрыДиалога.Фильтр = "Документы PDF (*.pdf)|*.pdf|Все файлы (*.*)|*.*";
    
    // Используем современный асинхронный метод платформы
    НачатьПомещениеФайловНаСервер(ОписаниеОповещения, , , ПараметрыДиалога, УникальныйИдентификатор);
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеПомещенияФайлов(РезультатПомещения, ДополнительныеПараметры) Экспорт
    
    // Проверяем, выбрал ли пользователь файл или закрыл диалог
    Если РезультатПомещения = Неопределено Или РезультатПомещения.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    // Обрабатываем результат
    Для каждого ФайлИзРезультата Из РезультатПомещения Цикл
        // Получаем информацию о загруженном файле
        ИмяФайла = ФайлИзРезультата.Имя;
        АдресВХ = ФайлИзРезультата.Адрес; // Ссылка на временное хранилище
        
        // Передаем адрес на сервер для дальнейшей обработки
        ОбработатьФайлНаСервере(ИмяФайла, АдресВХ);
    КонецЦикла;
    
КонецПроцедуры

Использование метода НачатьПомещениеФайловНаСервер() имеет ряд неоспоримых преимуществ:

  1. Полная поддержка стандартов асинхронности HTML5 без необходимости обязательной установки плагинов в браузер.
  2. Корректная обработка загрузки больших файлов благодаря оптимизированным механизмам передачи данных частями.
  3. Абсолютная безопасность кода: данные передаются напрямую в изолированное временное хранилище сеанса 1С на сервере.

Таким образом, следуя современным стандартам разработки в 1С и полностью отказавшись от синхронных вызовов на стороне клиента, вы навсегда избавите свои решения от ошибок модальности в веб-клиенте и обеспечите их стабильную работу в любых браузерах.

← На главную