Работа в веб-клиенте 1С кардинально отличается от работы в классическом тонком или толстом клиенте. Многие разработчики сталкиваются с тем, что привычный код, который отлично отрабатывал на собственном сервере, при переходе на веб-сервер начинает выдавать ошибки типа «Файл не обнаружен» или «Неправильный путь к файлу». Давайте разберемся, почему это происходит и как правильно организовать выгрузку файлов для пользователя.
При использовании веб-клиента браузер работает в так называемой «песочнице». Это строгие ограничения безопасности, которые не позволяют коду 1С, исполняемому на стороне сервера, напрямую обращаться к файловой системе компьютера пользователя. Когда вы пишете путь вида C:\Users\User\Desktop\..., сервер 1С пытается найти этот путь у себя, а не на вашем компьютере. Поскольку на сервере такого пути, как правило, нет, возникает ошибка.
Чтобы успешно передать файл с сервера на клиент, необходимо использовать механизм временного хранилища. Мы должны подготовить данные на сервере, «положить» их в специальную область памяти (временное хранилище), а затем инициировать передачу этих данных на сторону клиента через браузер.
ТекстовыйДокумент или ДвоичныеДанные) на стороне сервера.ПоместитьВоВременноеХранилище.ПолучитьФайл, передавая адрес из хранилища.Рассмотрим по шагам, как написать этот код правильно. Сначала создадим серверную функцию, которая подготавливает файл, а затем — клиентскую процедуру, которая «забирает» его к пользователю.
Шаг 1: Подготовка данных на сервере
Серверная процедура должна найти нужный файл и поместить его в хранилище. Обратите внимание, что мы используем ДвоичныеДанные для корректной передачи потока байтов.
&НаСервере
Процедура ПолучитьДанныеФайла(АдресФайла, ПутьКФайлуНаСервере, РезультатПоискаФайла = "") Экспорт
МассивФайлов = НайтиФайлы(ПутьКФайлуНаСервере);
Если МассивФайлов.Количество() > 0 Тогда
ПутьФайла = МассивФайлов[0].ПолноеИмя;
Попытка
ДанныеФайла = Новый ДвоичныеДанные(ПутьФайла);
ПоместитьВоВременноеХранилище(ДанныеФайла, АдресФайла);
Исключение
АдресФайла = Неопределено;
РезультатПоискаФайла = " Не удалось прочитать файл на сервере!";
КонецПопытки;
Иначе
АдресФайла = Неопределено;
РезультатПоискаФайла = " На сервере не найден файл " + ПутьКФайлуНаСервере + "!";
КонецЕсли;
КонецПроцедуры
Шаг 2: Клиентская обработка сохранения
На клиенте мы используем полученный адрес для инициирования загрузки. Мы не указываем жесткий путь, а передаем имя файла, которое будет предложено пользователю по умолчанию.
&НаКлиенте
Процедура ВыгрузитьНаЛокальныйПк(Адрес, ИмяФайла)
// Генерируем уникальный идентификатор для временного хранилища
АдресФайлаВоВременномХранилище = ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор);
РезультатПоискаФайла = "";
// Вызываем серверный метод для заполнения хранилища
ПолучитьДанныеФайла(АдресФайлаВоВременномХранилище, Адрес, РезультатПоискаФайла);
Если АдресФайлаВоВременномХранилище = Неопределено Тогда
Сообщить("Ошибка: " + РезультатПоискаФайла);
Иначе
// Браузер сам откроет окно сохранения, путь игнорируется
ПолучитьФайл(АдресФайлаВоВременномХранилище, ИмяФайла, Ложь);
КонецЕсли;
КонецПроцедуры
Помните о следующих нюансах:
ПолучитьФайл всегда вызывает интерактивный диалог сохранения. Это стандарт безопасности, и обойти его нельзя.Записать() на стороне сервера, если вы планируете, что их откроет пользователь — сервер и клиент физически разделены.Используя этот подход, вы избавитесь от ошибок «Путь не найден» и обеспечите пользователям удобный механизм получения отчетов и выгрузок в веб-интерфейсе 1С. Если вы планируете массовую выгрузку, реализуйте логику последовательного вызова ПолучитьФайл для каждого объекта, либо упаковывайте файлы в ZIP-архив на сервере и скачивайте одним файлом.