При работе в веб-клиенте 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда привычный синхронный код вызова диалога выбора файла перестает работать. При попытке выполнить методы вроде УстановитьРасширениеРаботыСФайлами() или Диалог.Выбрать() система выдает критическое предупреждение: «1С:Предприятие использование модальных окон в данном режиме запрещено». При этом включение настройки «Использовать модальный режим» в свойствах конфигурации не помогает. Разберем подробнее, почему возникает эта проблема и как правильно реализовать выбор файлов в веб-клиенте.
Проанализируем архитектурные особенности современных браузеров (Google Chrome, Mozilla Firefox, Microsoft Edge). Все веб-браузеры работают в однопоточном асинхронном режиме JavaScript. По этой причине разработчики браузеров отказались от поддержки синхронных блокирующих вызовов, которые полностью останавливают выполнение потока интерфейса.
Начиная с платформы 1С:Предприятие 8.3.10, блокировка синхронных вызовов в веб-клиенте стала принудительной. Настройка конфигурации «Режим использования модальности = Использовать» распространяется только на тонкий и толстый клиенты. В веб-клиенте использование модальных окон запрещено на уровне платформы, независимо от настроек базы. Поэтому любой попытке вызвать синхронный метод диалога система отвечает ошибкой.
Рассмотрим важную деталь, о которой часто забывают. Если ваша задача заключается только в том, чтобы дать пользователю выбрать файл на диске и загрузить его во временное хранилище на сервере, устанавливать «Расширение работы с файлами» вообще не требуется!
Веб-клиент способен выполнять базовую загрузку файлов с помощью встроенных средств HTML5 через асинхронные методы платформы:
НачатьПомещениеФайла() или НачатьПомещениеФайлов()ПоместитьФайлНаСерверАсинх()Расширение работы с файлами требуется исключительно в случаях, когда клиенту нужен прямой доступ к локальной файловой системе: проверка существования конкретного пути, программный обход каталогов на диске пользователя или сохранение файла в фиксированную папку без участия диалога браузера.
Рассмотрим традиционный способ перевода кода на асинхронные рельсы через объекты ОписаниеОповещения (Callback-функции). Этот вариант подходит для всех версий платформы 8.3.
Разберем алгоритм по шагам:
УстановитьРасширениеРаботыСФайлами() вызываем асинхронный метод НачатьУстановкуРасширенияРаботыСФайлами().ОписаниеОповещения, указывающий на экспортную процедуру-обработчик.Диалог.Показать().Посмотрим на пример реализации кода на клиенте:
&НаКлиенте
Процедура ВыбратьФайл(Команда)
// Шаг 1. Создаем оповещение для завершения установки/проверки расширения
ОповещениеПослеУстановки = Новый ОписаниеОповещения("ПослеПодключенияРасширения", ЭтотОбъект);
// Шаг 2. Асинхронно подключаем расширение работы с файлами
НачатьУстановкуРасширенияРаботыСФайлами(ОповещениеПослеУстановки);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПодключенияРасширения(Подключено, ДополнительныеПараметры) Экспорт
Если Не Подключено Тогда
Возврат; // Пользователь отказался от установки или возникла ошибка
КонецЕсли;
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл для импорта";
Диалог.Фильтр = "Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*";
// Шаг 3. Создаем оповещение для обработки выбора файла
ОповещениеВыбораФайла = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект);
// Шаг 4. Показываем диалог асинхронно
Диалог.Показать(ОповещениеВыбораФайла);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы <> Неопределено И ВыбранныеФайлы.Количество() > 0 Тогда
ИмяВыбранногоФайла = ВыбранныеФайлы[0];
ПоказатьОповещениеПользователя("Выбран файл",, ИмяВыбранногоФайла);
КонецЕсли;
КонецПроцедуры
Начиная с версии платформы 8.3.18, в 1С доступен современный синтаксис асинхронного программирования с использованием ключевых слов Асинх и Ждать. Это позволяет писать линейный и читаемый код без разбиения алгоритма на множественные процедуры-обработчики.
Рассмотрим, как выглядит тот же пример с использованием новых возможностей платформы:
&НаКлиенте
Асинх Процедура ВыбратьФайлСовременнымСпособом(Команда)
// Асинхронно подключаем расширение
Установлено = Ждать УстановитьРасширениеРаботыСФайламиАсинх();
Если Не Установлено Тогда
Возврат;
КонецЕсли;
// Настраиваем диалог
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл";
Диалог.Фильтр = "Все файлы (*.*)|*.*";
// Ждем результат выбора пользователя без блокировки интерфейса
ВыбранныеФайлы = Ждать Диалог.ВыбратьАсинх();
Если ВыбранныеФайлы <> Неопределено И ВыбранныеФайлы.Количество() > 0 Тогда
ПутьКФайлу = ВыбранныеФайлы[0];
// Выполняем дальнейшую обработку файла...
КонецЕсли;
КонецПроцедуры
Если в вашей конфигурации накопилось много старого синхронного кода, платформой предусмотрен встроенный инструмент автоматического переписывания процедур.
Проанализируем процесс автоматической трансформации кода:
Конфигуратор самостоятельно проанализирует контекст вызовов УстановитьРасширениеРаботыСФайлами или Диалог.Выбрать и перепишет код на использование ОписаниеОповещения или синтаксис Асинх / Ждать.
В конфигурациях, разработанных на базе Библиотеки Стандартных Подсистем (БСП), не требуется писать низкоуровневый код проверки расширений. Для этого существует общий модуль ФайловаяСистемаКлиент.
Посмотрим на пример загрузки файла через БСП:
&НаКлиенте
Процедура ЗагрузитьФайлЧерезБСП(Команда)
ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
ПараметрыЗагрузки.Заголовок = "Выберите файл для обработки";
ПараметрыЗагрузки.Фильтр = "Текст (*.txt)|*.txt";
Оповещение = Новый ОписаниеОповещения("ПослеЗагрузкиФайлаБСП", ЭтотОбъект);
// Метод автоматически обработает наличие расширения и диалог
ФайловаяСистемаКлиент.ЗагрузитьФайл(Оповещение, ПараметрыЗагрузки);
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗагрузкиФайлаБСП(ПомещенныйФайл, ДополнительныеПараметры) Экспорт
Если ПомещенныйФайл <> Неопределено Тогда
// Файл успешно помещен во временное хранилище
АдресХранилища = ПомещенныйФайл.Адрес;
ИмяФайла = ПомещенныйФайл.Имя;
КонецЕсли;
КонецПроцедуры
При работе асинхронных диалогов в веб-клиенте важно учитывать особенности настроек безопасности браузера:
Подводя итог: для успешной работы с файлами в веб-клиенте необходимо полностью отказаться от синхронных методов и перейти на использование асинхронных процедур платформы или готовых функций БСП.