Работа с файловой системой в веб-клиенте 1С существенно отличается от работы в тонком или толстом клиенте. Основная сложность заключается в том, что браузер — это изолированная среда, и из соображений безопасности он не позволяет программному коду свободно «гулять» по папкам пользователя. При попытке передать файлы по одному с помощью НачатьПомещениеФайла() пользователь сталкивается с тем, что система запрашивает подтверждение на каждый отдельный объект. Если файлов 50, это превращается в кошмар для пользователя.
В данной статье мы разберем, как реализовать массовую передачу файлов, минимизировав количество интерактивных запросов, и почему привычные методы работы с каталогами могут не срабатывать в веб-интерфейсе. Мы проанализируем ситуацию, изучим особенности асинхронного программирования в 1С и предложим готовые варианты реализации.
Когда мы работаем в веб-клиенте, параметр Интерактивно в методах помещения файлов почти всегда должен принимать значение Истина. Это не прихоть платформы 1С, а требование безопасности современных браузеров (Chrome, Firefox, Safari). Браузер должен быть уверен, что пользователь осознанно передает данные сайту. Если попытаться программно перебрать файлы в цикле и отправлять их «тихо», система выдаст ошибку или будет закидывать пользователя окнами подтверждения.
Разберем, как обойти это ограничение, используя возможности платформы для групповой обработки файлов.
Самый правильный способ для старых версий платформы (до 8.3.18) — это использование метода НачатьПомещениеФайлов(). В отличие от метода для одного файла, он позволяет передать целый массив описаний файлов за один вызов. Это критически важно: один вызов метода означает один интерактивный запрос к пользователю.
Рассмотрим пример реализации. Сначала нам нужно подготовить ДиалогВыбораФайла и перевести его в режим множественного выбора. Обратите внимание, что режим ВыборКаталога в веб-клиенте часто вызывает ошибки при попытке помещения файлов, поэтому мы будем использовать режим открытия с флагом множественного выбора.
&НаКлиенте
Процедура ЗагрузитьФайлы(Команда)
// Создаем диалог выбора файлов
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.МножественныйВыбор = Истина;
Диалог.Заголовок = "Выберите файлы для загрузки на сервер";
// Описываем оповещение, которое сработает после выбора и загрузки
Оповещение = Новый ОписаниеОповещения("ПослеПомещенияФайлов", ЭтотОбъект);
// Важный момент: передаем диалог в параметр НаборПомещаемыхФайлов
НачатьПомещениеФайлов(Оповещение, , Диалог, Истина, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайлов(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
// Результат — это массив объектов ОписаниеПомещенногоФайла
Для Каждого Файл Из Результат Цикл
Сообщить("Файл помещен во временное хранилище: " + Файл.Имя);
// Здесь можно вызвать серверный метод для обработки Адрес
ОбработатьФайлНаСервере(Файл.Адрес, Файл.Имя);
КонецЦикла;
КонецПроцедуры
В этом примере мы решаем главную проблему: пользователь выбирает 50 файлов в одной папке (например, через Ctrl+A), нажимает «Открыть», и система один раз запрашивает разрешение на доступ. Все выбранные файлы уходят на сервер пакетом.
Если вы работаете на платформе версии 8.3.18 и выше, крайне рекомендуется отказаться от НачатьПомещениеФайлов в пользу асинхронных функций. Они делают код линейным и более читаемым. Вместо процедур-оповещений мы используем конструкцию Ждать.
Выясним, как это выглядит на практике. Метод ПоместитьФайлыНаСерверАсинх() возвращает массив результатов, и мы можем обработать его сразу в той же процедуре.
&НаКлиенте
Асинх Процедура ЗагрузитьФайлыСовременно()
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.МножественныйВыбор = Истина;
// Вызываем диалог и ждем выбора пользователя
ВыбранныеФайлы = Ждать Диалог.ВыбратьАсинх();
Если ВыбранныеФайлы <> Неопределено Тогда
// Формируем массив описаний файлов для загрузки
МассивФайловДляЗагрузки = Новый Массив;
Для Каждого ПутьКФайлу Из ВыбранныеФайлы Цикл
Описание = Новый ОписаниеПередаваемогоФайла(ПутьКФайлу);
МассивФайловДляЗагрузки.Добавить(Описание);
КонецЦикла;
// Помещаем файлы на сервер одним асинхронным вызовом
Результат = Ждать ПоместитьФайлыНаСерверАсинх(,,, МассивФайловДляЗагрузки, УникальныйИдентификатор);
// Обрабатываем результат
Для Каждого ПомещенныйФайл Из Результат Цикл
Если ПомещенныйФайл.ФайлПомещен Тогда
Сообщить("Успешно: " + ПомещенныйФайл.СсылкаНаФайл.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Многие разработчики пытаются использовать РежимДиалогаВыбораФайла.ВыборКаталога, чтобы пользователь просто указал папку, а программа сама нашла в ней все файлы. Проанализируем, почему это не работает в веб-клиенте. Стандарты безопасности браузеров не позволяют веб-приложению получить список имен файлов в папке без явного выбора этих файлов пользователем.
Если вам критически важно работать именно с папкой, существует два обходных пути:
УстановитьРасширениеРаботыСФайлами() у вас появится возможность использовать метод НайтиФайлы() на клиенте. Однако даже с ним при первом обращении к диску возникнет интерактивный запрос.ПроверкаПеретаскивания и ОкончаниеПеретаскивания даст вам массив объектов Файл, которые можно сразу отправить на сервер.Разберем ситуацию, когда файлов не только много, но они еще и тяжелые. При использовании веб-клиента данные передаются через HTTP-протокол. Посмотрим на возможные «подводные камни»:
maxAllowedContentLength в IIS).Если вы столкнулись с подобным, стратегию лучше изменить: запрашивать массив файлов один раз, а затем в цикле по одному отправлять их на сервер, используя ПоместитьФайлНаСерверАсинх(). Поскольку права на эти файлы уже получены в рамках текущего сеанса после выбора в диалоге, повторных вопросов браузер задавать не будет (при условии правильной настройки ОписаниеПередаваемогоФайла).
Для реализации задачи по загрузке нескольких файлов в веб-клиенте мы рекомендуем использовать множественный выбор в диалоге открытия файлов в сочетании с асинхронными методами платформы. Это наиболее стабильный и «чистый» путь, который не требует установки дополнительных компонент и корректно воспринимается всеми современными браузерами. Помните, что ключ к успеху в веб-клиенте — это группировка операций загрузки для минимизации интерактивного взаимодействия с пользователем.