При разработке механизмов загрузки файлов в управляемом приложении, особенно для работы в веб-клиенте, программисты часто сталкиваются с типом данных СсылкаНаФайл. Возникает резонный вопрос: как создать этот объект программно с помощью оператора Новый? В этой статье мы разберем природу этого объекта, выясним, почему у него нет конструктора, и научимся правильно использовать его для загрузки файлов без использования расширения работы с файлами.
Рассмотрим важную техническую особенность: объект СсылкаНаФайл невозможно создать вручную через стандартный конструктор Новый СсылкаНаФайл(). Если мы заглянем в синтакс-помощник, то увидим, что описание конструктора для этого типа отсутствует. Это не ошибка платформы, а осознанное проектное решение, продиктованное архитектурой безопасности современных браузеров и операционных систем.
Проанализируем ситуацию: браузер (веб-клиент) не позволяет скриптам просто так обращаться к файловой системе пользователя. Чтобы программа получила доступ к файлу, пользователь должен совершить интерактивное действие — выбрать файл в диалоге или перетащить его в окно приложения. В момент этого действия операционная система передает браузеру так называемый «дескриптор» файла, который платформа 1С оборачивает в объект типа СсылкаНаФайл. Таким образом, этот объект является «доверенным билетом», подтверждающим право платформы прочитать конкретный файл.
Самый распространенный способ получения этого объекта — использование механизма Drag-and-Drop. Для того чтобы реализовать это в своей форме, выполним следующие шаги:
СпособПеретаскиванияФайлов.Ссылка на файл. Это критически важный момент: именно эта настройка заставляет платформу генерировать объекты нужного нам типа вместо обычных строк с путями.После этого нам необходимо создать обработчик события Перетаскивание. Разберем пример кода, который обрабатывает полученные данные:
&НаКлиенте
Процедура СписокПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
СтандартнаяОбработка = Ложь;
// ПараметрыПеретаскивания.Значение может содержать один объект или массив
МассивСсылок = Новый Массив;
Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Массив") Тогда
МассивСсылок = ПараметрыПеретаскивания.Значение;
ИначеЕсли ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("СсылкаНаФайл") Тогда
МассивСсылок.Добавить(ПараметрыПеретаскивания.Значение);
КонецЕсли;
Если МассивСсылок.Количество() > 0 Тогда
ЗагрузитьФайлыНаСервер(МассивСсылок);
КонецЕсли;
КонецПроцедуры
Основное преимущество использования СсылкаНаФайл заключается в возможности загрузки данных в веб-клиенте без установки Расширения работы с файлами. Когда мы используем обычные пути (строки), браузер требует расширение для доступа к диску. Но если у нас на руках есть СсылкаНаФайл, платформа уже имеет санкционированный доступ.
Для помещения таких файлов во временное хранилище мы используем асинхронный метод НачатьПомещениеФайловНаСервер. Проанализируем, как передать массив ссылок в эту процедуру:
&НаКлиенте
Процедура ЗагрузитьФайлыНаСервер(МассивСсылок)
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗагрузкиФайлов", ЭтотОбъект);
// Используем вариант синтаксиса, принимающий массив СсылкаНаФайл
НачатьПомещениеФайловНаСервер(ОписаниеОповещения, , , , МассивСсылок, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗагрузкиФайлов(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
Для Каждого ОписаниеФайла Из Результат Цикл
// ОписаниеФайла имеет тип ОписаниеПомещенногоФайла
Сообщить("Файл загружен: " + ОписаниеФайла.Имя + ", Адрес: " + ОписаниеФайла.Адрес);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Поскольку СсылкаНаФайл содержит информацию о файле еще до его фактической отправки на сервер, мы можем выполнить предварительную проверку. Это сэкономит трафик и время пользователя. У объекта СсылкаНаФайл есть полезные свойства: Имя и Размер.
Рассмотрим пример валидации размера и расширения файла:
&НаКлиенте
Функция ФайлПрошелВалидацию(ТекущаяСсылка)
// Проверка расширения (через анализ имени)
Если СтрЗаканчивается(НРег(ТекущаяСсылка.Имя), ".exe") Тогда
Сообщить("Загрузка исполняемых файлов запрещена!");
Возврат Ложь;
КонецЕсли;
// Проверка размера (в байтах). Например, ограничение 5 Мб.
МаксРазмер = 5 * 1024 * 1024;
Если ТекущаяСсылка.Размер > МаксРазмер Тогда
Сообщить("Файл " + ТекущаяСсылка.Имя + " слишком большой!");
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
Важный нюанс для Веб-клиента: Обращение к свойству СсылкаНаФайл.Файл в веб-клиенте без расширения работы с файлами вызовет ошибку. Это происходит потому, что свойство Файл возвращает объект типа Файл, который требует полного доступа к файловой системе. Поэтому для получения имени и размера используйте напрямую свойства самого объекта СсылкаНаФайл.
Часто возникает путаница между СсылкаНаФайл и ОписаниеПередаваемогоФайла. Выясним разницу:
Новый), указывая путь к файлу на диске и адрес в хранилище. Она работает только там, где есть прямой доступ к файловой системе (тонкий клиент или веб-клиент с расширением).В современных конфигурациях рекомендуется отдавать предпочтение методам, работающим через СсылкаНаФайл, так как это делает ваш интерфейс более дружелюбным к пользователям веб-клиента, избавляя их от необходимости устанавливать дополнительные расширения в браузер.
Подведем итог: если вам нужно программно «создать» СсылкаНаФайл, знайте — это невозможно сделать через конструктор. Вам нужно настроить интерфейс так, чтобы платформа сама предоставила вам эти объекты. Используйте свойство формы СпособПеретаскиванияФайлов = Ссылка на файл и обрабатывайте полученные массивы в асинхронных методах помещения файлов. Это обеспечит стабильную работу вашего кода в любых условиях, включая работу через веб-браузеры.