Как реализовать загрузку и сохранение файлов в веб-клиенте 1С без использования расширения браузера?

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

Работа с файловой системой в веб-клиенте 1С:Предприятие всегда была сопряжена с определенными трудностями. Основная проблема заключается в том, что современные браузеры (Google Chrome, Mozilla Firefox, Microsoft Edge) из соображений безопасности ограничивают доступ веб-приложений к локальным файлам пользователя. Раньше для обхода этих ограничений использовалось специальное «Расширение для работы с файлами», однако его установка требует дополнительных действий от пользователя и не всегда возможна в корпоративной среде. Разберем подробно, как реализовать загрузку и сохранение файлов, используя только стандартные возможности платформы, которые работают «из коробки».

Причина возникновения ошибки «Расширение для работы с файлами не подключено»

Когда мы используем старые методы, такие как ПоместитьФайл или НачатьПомещениеФайла без должной настройки асинхронности, платформа 1С пытается вызвать низкоуровневые API операционной системы через расширение браузера. Если оно не установлено или не разрешено в настройках браузера, пользователь получает блокирующую ошибку. Проанализируем ситуацию: начиная с версии 8.3.15, 1С перешла на новую модель асинхронности, которая использует нативные механизмы HTML5 (File API). Если же вы работаете на более ранних версиях (как автор темы на 8.3.10), нам нужно использовать методы, которые максимально дружелюбны к браузерной «песочнице».

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

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


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

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

Решение 2: Правильная работа с НачатьПомещениеФайла (одиночный выбор)

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

Рассмотрим правильный подход к обработке результата:


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

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

Проблема «Неопределено» во временном хранилище

Выясним причину, почему иногда ПолучитьИзВременногоХранилища на сервере возвращает Неопределено, хотя адрес файла вроде бы получен. Это классическая проблема жизненного цикла данных в веб-клиенте. Запомните важное правило: при вызове методов помещения файла в веб-клиенте необходимо обязательно передавать УникальныйИдентификатор формы в качестве параметра ИдентификаторФормы (обычно это 5-й или 6-й параметр метода).

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

Особенности сохранения файлов в веб-клиенте

Рассмотрим ситуацию с обратной операцией — сохранением файла на диск пользователя. Здесь ограничения браузеров еще строже. Без расширения работы с файлами вы не можете:

Метод ПолучитьФайл в веб-клиенте без расширения работает как стандартная «загрузка» в браузере. Файл просто попадает в папку «Загрузки» (Downloads) с тем именем, которое было передано в параметрах. Повлиять на этот процесс из кода 1С невозможно по правилам безопасности HTML5.

Современный подход: методы «Асинх» (Платформа 8.3.15+)

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


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

Настройка веб-сервера для больших файлов

Иногда код написан верно, но в веб-клиенте файлы больше определенного размера (например, 30 МБ) не загружаются. Проанализируем ситуацию: это может быть ограничение не 1С, а веб-сервера (Apache или IIS). Если файл «отсекается» до того, как попадет в 1С, проверьте следующие настройки:

  1. Для IIS: параметр maxAllowedContentLength в файле web.config.
  2. Для Apache: директива LimitRequestBody в конфигурационном файле httpd.conf.

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

Подводя итог, можно сказать, что работа с файлами в веб-клиенте без расширения вполне реальна. Ключевыми факторами успеха являются использование асинхронных методов (предпочтительно с постфиксом Асинх или Начать...), обязательная передача УникальногоИдентификатора формы и понимание того, что в вебе мы всегда работаем через временное хранилище.

← На главную