При разработке прикладных решений на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с задачей выбора пути для сохранения файлов. Если в тонком или толстом клиенте эта задача решается тривиально, то в веб-клиенте возникают нюансы, связанные с архитектурой безопасности современных браузеров. Рассмотрим подробно, почему привычные методы могут не срабатывать и как правильно организовать работу с файловой системой в браузере.
Часто разработчики ошибочно полагают, что метод НачатьПолучениеКаталогаДокументов должен открывать интерактивное окно выбора папки. Проанализируем ситуацию: на самом деле этот метод предназначен для асинхронного получения пути к стандартному каталогу документов текущего пользователя операционной системы. Он не инициирует диалог с пользователем, а просто возвращает строку (или путь), которую система считает «домашней» папкой документов.
Посмотрим на пример кода, который часто вызывает вопросы:
&НаКлиенте
Процедура ИмяФайлаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Описание = Новый ОписаниеОповещения("ЗакончитьПолучениеКаталогаДокументов", ЭтотОбъект);
НачатьПолучениеКаталогаДокументов(Описание);
КонецПроцедуры
&НаКлиенте
Процедура ЗакончитьПолучениеКаталогаДокументов(Результат, Параметры) Экспорт
Если Результат <> "" Тогда
Объект.КаталогВыгрузки = Результат;
КонецЕсли;
КонецПроцедуры
В данном случае система просто подставит путь к папке «Мои документы», не спрашивая пользователя. Для реализации именно выбора произвольного каталога этот метод не подходит.
Выясним причину, по которой работа с файлами в веб-клиенте ограничена. Современные браузеры (Chrome, Firefox, Edge, Safari) работают в режиме «песочницы». Это означает, что веб-приложение не может просто так «гулять» по жесткому диску пользователя, просматривать структуру папок или записывать файлы в любое место без явного подтверждения.
Для платформы 1С это влечет за собой два важных правила:
ДиалогВыбораФайла в режиме выбора каталога.Если бизнес-логика требует, чтобы пользователь обязательно выбрал конкретный путь на диске, нам необходимо использовать объект ДиалогВыбораФайла. Разберем по шагам, как это реализовать асинхронно.
Прежде всего, важно помнить: в веб-клиенте перед вызовом диалога нужно убедиться, что установлено и подключено Расширение для работы с файлами. Рассмотрим пример реализации:
&НаКлиенте
Асинхрон Процедура ВыбратьКаталог()
// Проверяем, подключено ли расширение
Подключено = Ждать ПодключитьРасширениеРаботыСФайлами();
Если Не Подключено Тогда
Ждать УстановитьРасширениеРаботыСФайлами();
Возврат;
КонецЕсли;
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
Диалог.Заголовок = "Выберите каталог для сохранения данных";
// Используем асинхронный метод Показать()
ВыбранныеФайлы = Ждать Диалог.Выбрать();
Если ВыбранныеФайлы <> Неопределено Тогда
Объект.КаталогВыгрузки = ВыбранныеФайлы[0];
КонецЕсли;
КонецПроцедуры
В этом примере мы используем современный синтаксис Асинхрон / Ждать (доступен в новых версиях платформы 8.3). Метод ПодключитьРасширениеРаботыСФайлами() крайне важен — без него в веб-клиенте режим ВыборКаталога может быть недоступен или вызовет ошибку выполнения.
Проанализируем ситуацию, когда мы не хотим заставлять пользователя устанавливать дополнительные расширения браузера. В этом случае мы должны следовать стандартному поведению веб-приложений: «Сервер готовит файл — Клиент его скачивает».
В этой парадигме мы не спрашиваем путь до формирования файла. Мы формируем файл, кладем его во временное хранилище, а затем вызываем метод ПолучитьФайлССервера. Браузер сам откроет стандартное окно сохранения (если включена соответствующая опция в браузере) или автоматически поместит файл в «Загрузки».
Рассмотрим программную реализацию этого подхода:
&НаСервере
Функция СформироватьФайлНаСервере()
// Создаем текстовый документ или двоичные данные
Текст = Новый ТекстовыйДокумент;
Текст.УстановитьТекст("Данные для выгрузки...");
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
Текст.Записать(ИмяВременногоФайла);
// Помещаем во временное хранилище
ДанныеФайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
Адрес = ПоместитьВоВременноеХранилище(ДанныеФайла, УникальныйИдентификатор);
Возврат Адрес;
КонецФункции
&НаКлиенте
Асинхрон Процедура СохранитьФайл()
АдресХранилища = СформироватьФайлНаСервере();
// Параметры получения файла
ПараметрыФайла = Новый ПараметрыПолученияФайлов(Истина); // Истина - интерактивно
ОписаниеФайла = Новый ОписаниеПередаваемогоФайла("Выгрузка.txt", АдресХранилища);
МассивФайлов = Новый Массив;
МассивФайлов.Добавить(ОписаниеФайла);
Ждать ПолучитьФайлыССервера(МассивФайлов, , ПараметрыФайла);
КонецПроцедуры
При таком подходе нам не нужно знать путь к каталогу в коде 1С. Мы передаем управление браузеру, который берет на себя взаимодействие с файловой системой пользователя. Это самый стабильный и рекомендуемый способ для работы в веб-клиенте.
Выясним преимущества и недостатки каждого метода, чтобы выбрать оптимальный для вашей задачи:
В процессе разработки для 1С 8.3 важно различать старые асинхронные методы (использующие ОписаниеОповещения) и новые (использующие Ждать). Платформа постепенно переходит к модели Promise-подобных вызовов. Если ваша версия платформы позволяет (8.3.18+), всегда отдавайте предпочтение Асинхрон / Ждать, так как это делает код более читаемым и линейным, исключая «ад обратных вызовов» (callback hell).
Например, вместо создания отдельной процедуры-обработчика для НачатьПодключениеРасширенияРаботыСФайлами, мы просто пишем Результат = Ждать ПодключитьРасширениеРаботыСФайлами(), что значительно упрощает отладку и понимание логики программы.
Таким образом, мы выяснили, что прямой выбор каталога в веб-клиенте — это операция, требующая особого внимания к безопасности браузера. Либо мы используем расширение для полноценного доступа, либо используем стандартные механизмы передачи файлов, принятые в веб-среде.