Как правильно реализовать загрузку и обработку файлов через веб-сервер в 1С:Предприятие 8.3

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

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

Анализ проблемы: почему код не работает через веб-сервер

Проанализируем ситуацию, описанную в исходном вопросе. Основная проблема заключается в попытке использовать методы, предназначенные для прямой работы с файловой системой, в условиях «песочницы» веб-браузера. Рассмотрим ключевые ошибки:

  1. Ограничения веб-клиента: В браузере метод ДвоичныеДанные.Записать() по конкретному пути (например, в C:\Temp\) не может быть выполнен без установленного «Расширения работы с файлами». Браузеры из соображений безопасности блокируют прямой доступ к локальным дискам пользователя.
  2. Некорректная асинхронная логика: В коде автора наблюдается избыточный двойной вызов метода НачатьПомещениеФайловНаСервер. Сначала файлы выбираются диалогом и помещаются в хранилище, а затем во втором оповещении они пытаются «поместиться» еще раз, что создает путаницу в адресах и данных.
  3. Жизненный цикл временного хранилища: При работе через веб-сервер крайне важно правильно привязывать данные к УникальныйИдентификатор формы. Если этого не сделать, данные могут исчезнуть из хранилища до того, как сервер успеет их обработать.

Шаг 1. Организация выбора файлов и первичной загрузки

Для начала разберем, как правильно инициировать выбор файлов. Вместо устаревших синхронных методов мы должны использовать асинхронный метод НачатьПомещениеФайловНаСервер. Это позволяет пользователю выбрать файлы в интерфейсе браузера, как, например, при поиске и загрузке изображений, после чего платформа автоматически загрузит их во временное хранилище на сервере 1С.

Рассмотрим правильный пример инициации процесса на клиенте:


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

Шаг 2. Обработка результата во временном хранилище

После того как пользователь выбрал файлы, управление передается в процедуру оповещения. В этот момент файлы уже находятся во временном хранилище. Нам не нужно вызывать НачатьПомещениеФайловНаСервер повторно. Нам нужно получить адреса этих файлов и передать их на серверную часть обработки.

Проанализируем структуру процедуры завершения:


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

Шаг 3. Серверная обработка данных

Это самый важный этап. На сервере мы можем безопасно извлечь данные из ВременноеХранилище, прочитать их содержимое и заполнить необходимые реквизиты формы. Попытка записать файл на диск сервера через ДвоичныеДанные.Записать() в веб-клиенте часто лишена смысла, так как мы работаем с данными «в памяти».

Разберем, как прочитать XML из хранилища без сохранения на физический диск сервера:


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

Особенности работы с расширением файловой системы

Выясним причину, по которой многие программисты пытаются использовать КаталогВременныхФайлов() и ДвоичныеДанные.Записать() на клиенте. В тонком клиенте это позволяет подготовить файл локально. Однако в веб-клиенте (браузере) функция КаталогВременныхФайлов() возвращает виртуальный путь, недоступный для прямой записи кодом 1С.

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

  1. Проверить подключение расширения методом НачатьПодключениеРасширенияРаботыСФайлами.
  2. Если расширение не установлено, предложить пользователю его установить через НачатьУстановкуРасширенияРаботыСФайлами.
  3. Только при наличии расширения методы прямой работы с путями типа C:\Temp начнут функционировать в браузере.

Рекомендации по отладке через веб-сервер

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

1. Журнал регистрации: Используйте метод ЗаписьЖурналаРегистрации на сервере. Записывайте туда количество переданных адресов, их валидность и ошибки обработки. Это единственный надежный способ «увидеть», что происходит на сервере, особенно при взаимодействии с внешними системами.

2. Сообщить пользователю: Выводите промежуточные статусы на клиент через ОбщегоНазначенияКлиентСервер.СообщитьПользователю. Это поможет понять, на каком этапе (загрузка в хранилище или чтение на сервере) происходит сбой.

3. Проверка индекса: Ошибка Индекс за пределами значений, упомянутая в сообщении 6, часто возникает, когда массив ПомещенныеФайлы оказывается пустым или когда логика кода пытается обратиться к колонке таблицы формы, которая не была проинициализирована на сервере. Всегда добавляйте проверку Массив.Количество() > 0 перед обращением по индексу.

Итоги

Для стабильной работы обработки через веб-сервер мы рекомендуем придерживаться схемы: Загрузка в хранилище на клиенте -> Передача адреса на сервер -> Обработка данных из памяти на сервере. Это исключает зависимость от файловой системы клиентского компьютера и делает решение универсальным для любого браузера и типа клиента 1С, что подтверждается на примере интеграции с Битрикс24 для создания задач с файлами.

← На главную