Как организовать стандартный диалог выбора файла в веб-клиенте 1С и исправить ошибку модальных окон

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

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

Выясним причину: почему веб-клиент блокирует модальные окна

Проанализируем архитектурные особенности современных браузеров (Google Chrome, Mozilla Firefox, Microsoft Edge). Все веб-браузеры работают в однопоточном асинхронном режиме JavaScript. По этой причине разработчики браузеров отказались от поддержки синхронных блокирующих вызовов, которые полностью останавливают выполнение потока интерфейса.

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

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

Рассмотрим важную деталь, о которой часто забывают. Если ваша задача заключается только в том, чтобы дать пользователю выбрать файл на диске и загрузить его во временное хранилище на сервере, устанавливать «Расширение работы с файлами» вообще не требуется!

Веб-клиент способен выполнять базовую загрузку файлов с помощью встроенных средств HTML5 через асинхронные методы платформы:

  1. НачатьПомещениеФайла() или НачатьПомещениеФайлов()
  2. ПоместитьФайлНаСерверАсинх()

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

Решение 1. Использование асинхронных методов с ОписаниемОповещения

Рассмотрим традиционный способ перевода кода на асинхронные рельсы через объекты ОписаниеОповещения (Callback-функции). Этот вариант подходит для всех версий платформы 8.3.

Разберем алгоритм по шагам:

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

Посмотрим на пример реализации кода на клиенте:


&НаКлиенте
Процедура ВыбратьФайл(Команда)
    
    // Шаг 1. Создаем оповещение для завершения установки/проверки расширения
    ОповещениеПослеУстановки = Новый ОписаниеОповещения("ПослеПодключенияРасширения", ЭтотОбъект);
    
    // Шаг 2. Асинхронно подключаем расширение работы с файлами
    НачатьУстановкуРасширенияРаботыСФайлами(ОповещениеПослеУстановки);

КонецПроцедуры

&НаКлиенте
Процедура ПослеПодключенияРасширения(Подключено, ДополнительныеПараметры) Экспорт
    
    Если Не Подключено Тогда
        Возврат; // Пользователь отказался от установки или возникла ошибка
    КонецЕсли;

    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Заголовок = "Выберите файл для импорта";
    Диалог.Фильтр = "Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*";
    
    // Шаг 3. Создаем оповещение для обработки выбора файла
    ОповещениеВыбораФайла = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект);
    
    // Шаг 4. Показываем диалог асинхронно
    Диалог.Показать(ОповещениеВыбораФайла);

КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт

    Если ВыбранныеФайлы <> Неопределено И ВыбранныеФайлы.Количество() > 0 Тогда
        ИмяВыбранногоФайла = ВыбранныеФайлы[0];
        ПоказатьОповещениеПользователя("Выбран файл",, ИмяВыбранногоФайла);
    КонецЕсли;

КонецПроцедуры

Решение 2. Использование современных асинхронных функций (Асинх / Ждать)

Начиная с версии платформы 8.3.18, в 1С доступен современный синтаксис асинхронного программирования с использованием ключевых слов Асинх и Ждать. Это позволяет писать линейный и читаемый код без разбиения алгоритма на множественные процедуры-обработчики.

Рассмотрим, как выглядит тот же пример с использованием новых возможностей платформы:


&НаКлиенте
Асинх Процедура ВыбратьФайлСовременнымСпособом(Команда)

    // Асинхронно подключаем расширение
    Установлено = Ждать УстановитьРасширениеРаботыСФайламиАсинх();
    Если Не Установлено Тогда
        Возврат;
    КонецЕсли;

    // Настраиваем диалог
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Заголовок = "Выберите файл";
    Диалог.Фильтр = "Все файлы (*.*)|*.*";

    // Ждем результат выбора пользователя без блокировки интерфейса
    ВыбранныеФайлы = Ждать Диалог.ВыбратьАсинх();

    Если ВыбранныеФайлы <> Неопределено И ВыбранныеФайлы.Количество() > 0 Тогда
        ПутьКФайлу = ВыбранныеФайлы[0];
        // Выполняем дальнейшую обработку файла...
    КонецЕсли;

КонецПроцедуры

Решение 3. Автоматический рефакторинг в Конфигураторе 1С

Если в вашей конфигурации накопилось много старого синхронного кода, платформой предусмотрен встроенный инструмент автоматического переписывания процедур.

Проанализируем процесс автоматической трансформации кода:

  1. Откройте модуль формы или конфигурации с устаревшим кодом.
  2. Выделите текст процедуры с синхронными вызовами или нажмите правой кнопкой мыши в поле редактора.
  3. В контекстном меню перейдите в пункт «Рефакторинг» -> «Нерекомендуемые синхронные вызовы».
  4. Выберите команду «Преобразовать в асинхронную процедуру».

Конфигуратор самостоятельно проанализирует контекст вызовов УстановитьРасширениеРаботыСФайлами или Диалог.Выбрать и перепишет код на использование ОписаниеОповещения или синтаксис Асинх / Ждать.

Решение 4. Использование готовых механизмов БСП

В конфигурациях, разработанных на базе Библиотеки Стандартных Подсистем (БСП), не требуется писать низкоуровневый код проверки расширений. Для этого существует общий модуль ФайловаяСистемаКлиент.

Посмотрим на пример загрузки файла через БСП:


&НаКлиенте
Процедура ЗагрузитьФайлЧерезБСП(Команда)

    ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
    ПараметрыЗагрузки.Заголовок = "Выберите файл для обработки";
    ПараметрыЗагрузки.Фильтр = "Текст (*.txt)|*.txt";

    Оповещение = Новый ОписаниеОповещения("ПослеЗагрузкиФайлаБСП", ЭтотОбъект);
    
    // Метод автоматически обработает наличие расширения и диалог
    ФайловаяСистемаКлиент.ЗагрузитьФайл(Оповещение, ПараметрыЗагрузки);

КонецПроцедуры

&НаКлиенте
Процедура ПослеЗагрузкиФайлаБСП(ПомещенныйФайл, ДополнительныеПараметры) Экспорт

    Если ПомещенныйФайл <> Неопределено Тогда
        // Файл успешно помещен во временное хранилище
        АдресХранилища = ПомещенныйФайл.Адрес;
        ИмяФайла = ПомещенныйФайл.Имя;
    КонецЕсли;

КонецПроцедуры

Дополнительные настройки браузера

При работе асинхронных диалогов в веб-клиенте важно учитывать особенности настроек безопасности браузера:

Подводя итог: для успешной работы с файлами в веб-клиенте необходимо полностью отказаться от синхронных методов и перейти на использование асинхронных процедур платформы или готовых функций БСП.

← На главную