При разработке функционала для загрузки изображений или документов разработчики часто сталкиваются с неожиданным поведением платформы. Мы настроили фильтр по расширениям, в тонком и толстом клиентах он работает идеально, но стоит открыть конфигурацию через браузер (в веб-клиенте), как фильтр перестает действовать, и пользователю предлагаются к выбору абсолютно все файлы. Давайте подробно разберем эту ситуацию и найдем надежное решение.
Часто программисты пытаются использовать метод НачатьПомещениеФайла, передавая ему сразу настроенный диалог в качестве третьего параметра. Посмотрим на типичный пример кода, который вызывает проблемы в вебе:
Процедура ФайлыФайлСтрокаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
ТекущаяСтрока = Элементы.Файлы.ТекущиеДанные;
ОписаниеОповещения = Новый ОписаниеОповещения("ВыборФайлаЗавершение", ЭтотОбъект, ТекущаяСтрока);
Режим = РежимДиалогаВыбораФайла.Открытие;
Диалог = Новый ДиалогВыбораФайла(Режим);
// Попытка задать фильтр
Фильтр = "Файл фотографий (*.jpg; *.jpeg; *.png; *.bmp; *.gif)|*.jpg; *.jpeg; *.png; *.bmp; *.gif";
Диалог.Фильтр = Фильтр;
Диалог.МножественныйВыбор = Ложь;
// Передача диалога сразу в метод помещения файла
НачатьПомещениеФайла(ОписаниеОповещения, , Диалог, Истина, УникальныйИдентификатор);
СтандартнаяОбработка = Ложь;
КонецПроцедуры
В этом коде есть сразу несколько подводных камней, из-за которых веб-клиент игнорирует настройки.
Текстовый документ(*.txt)|*.txt. Если в строке фильтра допустить ошибки (например, лишние пробелы в перечислении масок), некоторые клиенты могут не распознать её корректно.НачатьПомещениеФайла при использовании параметра-диалога в браузере часто формирует стандартный HTML-элемент браузера без должной обработки сложных фильтров.Давайте выясним причину такого поведения веб-клиента. В архитектуре веба вызов файлового диалога 1С транслируется в обычный HTML-тег <input type="file" accept="...">. Разные браузеры и операционные системы по-разному считывают строку фильтра, переданную через атрибут accept.
Например, в операционной системе macOS сравнение масок файлов происходит строго с учетом регистра. Если синтаксис фильтра кажется браузеру некорректным, он просто проигнорирует ограничения, позволив пользователю выбрать любой файл. Платформа 1С лишь передает строку, а финальная отрисовка диалогового окна полностью лежит на совести операционной системы и браузера.
Кроме того, взаимодействие с локальной файловой системой в веб-клиенте жестко ограничено политиками безопасности. Для корректной работы сложных параметров диалога у пользователя должно быть установлено и включено Расширение для работы с файлами 1С. Но даже с ним передача диалога напрямую в метод загрузки может давать сбои.
Чтобы обойти "приколы" веб-клиента и заставить фильтр работать, нам необходимо отказаться от помещения файла одним махом. Разберем по шагам правильный, стабильный алгоритм:
ДиалогВыбораФайла и настраиваем его свойства (включая фильтр).Показать() непосредственно у самого диалога, передав ему оповещение.Посмотрим на пример правильной реализации:
&НаКлиенте
Процедура ФайлыФайлСтрокаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ТекущаяСтрока = Элементы.Файлы.ТекущиеДанные;
// Шаг 1: Готовим диалог отдельно
Режим = РежимДиалогаВыбораФайла.Открытие;
Диалог = Новый ДиалогВыбораФайла(Режим);
Диалог.Фильтр = "Изображения (*.jpg;*.jpeg;*.png)|*.jpg;*.jpeg;*.png";
Диалог.МножественныйВыбор = Ложь;
Диалог.Заголовок = "Выберите фотографию";
// Шаг 2: Показываем диалог асинхронно
Оповещение = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект, ТекущаяСтрока);
Диалог.Показать(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы = Неопределено Тогда
Возврат; // Пользователь отменил выбор
КонецЕсли;
// Получаем путь к выбранному файлу
ПутьКФайлу = ВыбранныеФайлы[0];
// Шаг 3: Теперь помещаем файл на сервер
ОповещениеПомещения = Новый ОписаниеОповещения("ВыборФайлаЗавершение", ЭтотОбъект, ДополнительныеПараметры);
// Используем современный метод (для платформы 8.3.15 и выше)
НачатьПомещениеФайлаНаСервер(ОповещениеПомещения, , , ПутьКФайлу, УникальныйИдентификатор);
КонецПроцедуры
Такой подход заставляет веб-клиент сначала четко отработать процедуру выбора файла через интерфейс ОС с применением переданных масок, и только потом инициирует загрузку данных по конкретному пути.
Рассмотрим еще два важных правила, которых стоит придерживаться при работе с файлами в современных конфигурациях 1С.
Во-первых, метод НачатьПомещениеФайла, который мы рассматривали в самом начале, признан устаревшим. Начиная с платформы 8.3.15, 1С рекомендует использовать методы НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера(). Они работают стабильнее и избавляют от лишней путаницы с передачей диалогов напрямую в параметры.
Во-вторых, если вы разрабатываете конфигурацию с внедренной Библиотекой стандартных подсистем (БСП), не нужно изобретать велосипед и писать низкоуровневый код с ДиалогВыбораФайла. БСП уже содержит готовые программные интерфейсы, которые учитывают все нюансы веб-клиента, браузеров и проверок расширения работы с файлами.
Рекомендуется использовать экспортные методы общего модуля ФайловаяСистемаКлиент. Вызов процедуры ПоказатьДиалогВыбора из этого модуля автоматически проверит доступность файловой системы, предложит пользователю установить расширение, если оно отсутствует, и корректно отрисует окно выбора с нужным вам фильтром расширений.