При разработке функционала загрузки файлов в 1С:Предприятие программисты часто сталкиваются с неожиданным поведением платформы в веб-клиенте. Код, который отлично работает в тонком или толстом клиенте, внезапно начинает выдавать ошибки при запуске через браузер. Рассмотрим подробнее одну из таких ситуаций: проблему с получением полного пути к файлу при использовании асинхронных методов помещения файлов на сервер.
Проанализируем ситуацию. Разработчик использует стандартный асинхронный метод НачатьПомещениеФайлаНаСервер. После выбора файла пользователем срабатывает обработчик завершения, в котором происходит попытка извлечь полное имя файла для отображения его на форме. В коде это выглядит примерно так:
&НаКлиенте
Процедура ЗавершениеОбратныйВызов(ОписаниеПомещенногоФайла, ДополнительныеПараметры) Экспорт
Если ОписаниеПомещенногоФайла = Неопределено Тогда
Возврат;
КонецЕсли;
// Попытка получить полный путь вызывает ошибку в веб-клиенте
frИмяФайлаЭксель = ОписаниеПомещенногоФайла.СсылкаНаФайл.Файл.ПолноеИмя;
КонецПроцедуры
При выполнении этого кода в тонком клиенте переменная frИмяФайлаЭксель успешно получает строку вида "C:\Users\Admin\Documents\Отчет.xlsx". Однако в веб-клиенте (например, в Mozilla Firefox или Google Chrome) на этой строке происходит сбой. При этом, если обратиться просто к короткому имени файла через ОписаниеПомещенногоФайла.СсылкаНаФайл.Имя, код отрабатывает без ошибок.
Разберем причины такого поведения. Основная причина кроется не в платформе 1С, а в политиках безопасности современных браузеров (Sandboxing). Браузеры намеренно скрывают полный путь к файлу на локальном компьютере пользователя. Это делается для того, чтобы сторонние веб-сайты не могли получить информацию о структуре каталогов пользователя или имени его учетной записи в операционной системе.
Когда вы выбираете файл через стандартный диалог браузера, веб-клиенту передается только содержимое файла и его короткое имя. Даже если попытаться получить путь, браузер подменит его на заглушку (например, "C:\fakepath\Отчет.xlsx") или вовсе вернет пустую строку. Платформа 1С:Предприятие вынуждена работать в рамках этих ограничений.
Посмотрим на объект Файл в контексте веб-клиента. В синтакс-помощнике указано, что для работы с параметрами файлов на веб-клиенте необходимо предварительно подключить расширение работы с файлами. Выясним, как это сделать правильно:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
#Если ВебКлиент Тогда
ПроверитьДоступностьРасширенияРаботыСФайлами(Истина);
#КонецЕсли
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьДоступностьРасширенияРаботыСФайлами(ПредлагатьУстановку = Истина)
ДополнительныеПараметры = Новый Структура("ПредлагатьУстановку", ПредлагатьУстановку);
Оповещение = Новый ОписаниеОповещения("ЗавершениеПодключенияРасширения", ЭтотОбъект, ДополнительныеПараметры);
НачатьПодключениеРасширенияРаботыСФайлами(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ЗавершениеПодключенияРасширения(Подключено, ДополнительныеПараметры) Экспорт
Если Подключено Тогда
Сообщить("Расширение работы с файлами успешно подключено.");
КонецЕсли;
КонецПроцедуры
Подключение расширения (плагина браузера) действительно расширяет возможности 1С в вебе. Однако, даже при активном плагине, свойство ПолноеИмя при интерактивном выборе файла может оставаться недоступным. Контекст безопасности "песочницы" браузера имеет более высокий приоритет. Тонкий клиент лишен этой проблемы, так как является полноценным десктопным приложением с прямым доступом к API Windows.
Если перед вами стоит задача показать пользователю имя загружаемого файла на форме, мы настоятельно рекомендуем отказаться от попыток получить полный локальный путь в веб-клиенте. Правильным архитектурным решением будет использование только короткого имени файла.
Перепишем наш код с учетом особенностей браузерной среды и рекомендаций платформы 1С:
&НаКлиенте
Процедура ЗагрузитьФайл()
ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов("Выберите файл Excel", Ложь, "*.xls|*.xlsx");
// Рекомендуется использовать множественный метод для новых версий платформы
Оповещение = Новый ОписаниеОповещения("ЗавершениеЗагрузки", ЭтотОбъект);
НачатьПомещениеФайловНаСервер(Оповещение, , , ПараметрыДиалога, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ЗавершениеЗагрузки(ПомещенныеФайлы, ДополнительныеПараметры) Экспорт
Если ПомещенныеФайлы = Неопределено Или ПомещенныеФайлы.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Получаем первый загруженный файл
ОписаниеФайла = ПомещенныеФайлы[0];
// Используем только короткое имя файла - это безопасно и работает везде!
frИмяФайлаЭксель = ОписаниеФайла.Имя;
// Дополнительные данные, которые мы можем безопасно получить
АдресФайлаВХранилище = ОписаниеФайла.Адрес;
Модифицированность = Истина;
КонецПроцедуры
Использование метода НачатьПомещениеФайловНаСервер (начиная с платформы 8.3.15) возвращает массив структур, где свойство Имя всегда корректно заполняется во всех клиентах. Это стандартизирует поведение системы и избавляет от лишних ошибок при обращении к сложной иерархии объектов.
Разберем по шагам, как правильно отлаживать подобные асинхронные вызовы, если код все же ведет себя непредсказуемо. Многие разработчики жалуются, что отладчик "проскакивает" процедуры обратного вызова в веб-клиенте.
web.config в корне публикации вашей базы должен быть установлен параметр debug="true"./debug (например: http://localhost/base/?/debug).Сообщить() для вывода значений переменных прямо в пользовательский интерфейс.Проанализировав все ограничения, можно сделать вывод: при разработке универсальных форм, которые будут работать и в тонком, и в веб-клиенте, абстрагируйтесь от локальной файловой системы пользователя. Серверу 1С для обработки данных вполне достаточно временного адреса файла (из хранилища) и его короткого имени (для сохранения или визуализации формата).