Как эффективно передать несколько файлов на сервер в веб-клиенте 1С

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

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

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

Причина проблемы: Безопасность браузера и интерактивность

Когда мы работаем в веб-клиенте, параметр Интерактивно в методах помещения файлов почти всегда должен принимать значение Истина. Это не прихоть платформы 1С, а требование безопасности современных браузеров (Chrome, Firefox, Safari). Браузер должен быть уверен, что пользователь осознанно передает данные сайту. Если попытаться программно перебрать файлы в цикле и отправлять их «тихо», система выдаст ошибку или будет закидывать пользователя окнами подтверждения.

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

Решение 1: Использование метода НачатьПомещениеФайлов

Самый правильный способ для старых версий платформы (до 8.3.18) — это использование метода НачатьПомещениеФайлов(). В отличие от метода для одного файла, он позволяет передать целый массив описаний файлов за один вызов. Это критически важно: один вызов метода означает один интерактивный запрос к пользователю.

Рассмотрим пример реализации. Сначала нам нужно подготовить ДиалогВыбораФайла и перевести его в режим множественного выбора. Обратите внимание, что режим ВыборКаталога в веб-клиенте часто вызывает ошибки при попытке помещения файлов, поэтому мы будем использовать режим открытия с флагом множественного выбора.


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

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

В этом примере мы решаем главную проблему: пользователь выбирает 50 файлов в одной папке (например, через Ctrl+A), нажимает «Открыть», и система один раз запрашивает разрешение на доступ. Все выбранные файлы уходят на сервер пакетом.

Решение 2: Современный подход через Promise (Async/Await)

Если вы работаете на платформе версии 8.3.18 и выше, крайне рекомендуется отказаться от НачатьПомещениеФайлов в пользу асинхронных функций. Они делают код линейным и более читаемым. Вместо процедур-оповещений мы используем конструкцию Ждать.

Выясним, как это выглядит на практике. Метод ПоместитьФайлыНаСерверАсинх() возвращает массив результатов, и мы можем обработать его сразу в той же процедуре.


&НаКлиенте
Асинх Процедура ЗагрузитьФайлыСовременно()
    
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.МножественныйВыбор = Истина;
    
    // Вызываем диалог и ждем выбора пользователя
    ВыбранныеФайлы = Ждать Диалог.ВыбратьАсинх();
    
    Если ВыбранныеФайлы <> Неопределено Тогда
        
        // Формируем массив описаний файлов для загрузки
        МассивФайловДляЗагрузки = Новый Массив;
        Для Каждого ПутьКФайлу Из ВыбранныеФайлы Цикл
            Описание = Новый ОписаниеПередаваемогоФайла(ПутьКФайлу);
            МассивФайловДляЗагрузки.Добавить(Описание);
        КонецЦикла;
        
        // Помещаем файлы на сервер одним асинхронным вызовом
        Результат = Ждать ПоместитьФайлыНаСерверАсинх(,,, МассивФайловДляЗагрузки, УникальныйИдентификатор);
        
        // Обрабатываем результат
        Для Каждого ПомещенныйФайл Из Результат Цикл
            Если ПомещенныйФайл.ФайлПомещен Тогда
                Сообщить("Успешно: " + ПомещенныйФайл.СсылкаНаФайл.Имя);
            КонецЕсли;
        КонецЦикла;
        
    КонецЕсли;
    
КонецПроцедуры

Ограничение на выбор папки в веб-клиенте

Многие разработчики пытаются использовать РежимДиалогаВыбораФайла.ВыборКаталога, чтобы пользователь просто указал папку, а программа сама нашла в ней все файлы. Проанализируем, почему это не работает в веб-клиенте. Стандарты безопасности браузеров не позволяют веб-приложению получить список имен файлов в папке без явного выбора этих файлов пользователем.

Если вам критически важно работать именно с папкой, существует два обходных пути:

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

Важные нюансы при загрузке больших объемов

Разберем ситуацию, когда файлов не только много, но они еще и тяжелые. При использовании веб-клиента данные передаются через HTTP-протокол. Посмотрим на возможные «подводные камни»:

Если вы столкнулись с подобным, стратегию лучше изменить: запрашивать массив файлов один раз, а затем в цикле по одному отправлять их на сервер, используя ПоместитьФайлНаСерверАсинх(). Поскольку права на эти файлы уже получены в рамках текущего сеанса после выбора в диалоге, повторных вопросов браузер задавать не будет (при условии правильной настройки ОписаниеПередаваемогоФайла).

Заключение

Для реализации задачи по загрузке нескольких файлов в веб-клиенте мы рекомендуем использовать множественный выбор в диалоге открытия файлов в сочетании с асинхронными методами платформы. Это наиболее стабильный и «чистый» путь, который не требует установки дополнительных компонент и корректно воспринимается всеми современными браузерами. Помните, что ключ к успеху в веб-клиенте — это группировка операций загрузки для минимизации интерактивного взаимодействия с пользователем.

← На главную