Как прочитать данные из файла в веб-клиенте 1С?

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

Разработка в веб-клиенте 1С накладывает на программиста ряд специфических ограничений, которые отсутствуют в тонком или толстом клиентах. Одной из самых трудоемких задач является прямое взаимодействие с файловой системой пользователя. Часто разработчики сталкиваются с ошибками вроде "не удалось получить свойство closeasync" или внезапным закрытием браузера при попытке прочитать несколько байт из файла. В этой статье мы подробно разберем, как правильно организовать чтение данных из локального файла в браузере, какие объекты использовать и как избежать типичных ошибок.

Особенности "песочницы" браузера и расширение работы с файлами

Прежде всего, нам необходимо осознать, что любой современный браузер работает в режиме строгой изоляции («песочницы»). Программный код внутри страницы не имеет прямого доступа к диску C:\ или любым другим путям. Чтобы 1С могла взаимодействовать с файлами на стороне клиента в веб-интерфейсе, обязательно должно быть установлено и подключено Расширение для работы с файлами. Без него объект ФайловыйПоток просто не сможет инициализироваться, что и приводит к неопределенным значениям свойств в JavaScript-коде платформы.

Рассмотрим ситуацию, когда нам нужно прочитать первые несколько символов из файла. В обычном приложении мы бы просто использовали ЧтениеТекста, но в веб-клиенте нам доступны только асинхронные методы. Вызов синхронных методов работы с файлами в браузере заблокирован на уровне архитектуры платформы.

Вариант 1. Чтение данных на стороне клиента через асинхронные потоки

Для того чтобы прочитать данные непосредственно в браузере, нам потребуется комбинация объектов ФайловыйПоток и ЧтениеДанных. Проанализируем правильную последовательность действий. Сначала необходимо открыть поток, затем передать его в объект чтения и вызвать асинхронную процедуру получения данных.

Ниже приведен пример кода, который реализует это чтение. Обратите внимание на использование ОписаниеОповещения — это ключевой механизм для работы в веб-клиенте.


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

&НаКлиенте
Процедура ЗавершениеЧтенияСимволов(Результат, ДополнительныеПараметры) Экспорт
    
    // В переменной 'Результат' содержатся прочитанные данные
    Сообщить("Прочитано: " + Результат);
    
    // Обязательно закрываем объект чтения и поток
    Чтение = ДополнительныеПараметры;
    Чтение.Закрыть();
    
КонецПроцедуры

Разберем, почему возникает ошибка closeasync, упомянутая в обсуждениях. Эта ошибка часто свидетельствует о том, что объект ЧтениеДанных не был создан должным образом из-за проблем с правами доступа или отсутствия расширения. Когда выполнение доходит до попытки закрытия потока (которая в веб-клиенте тоже асинхронная), система пытается обратиться к методу closeasync у null-объекта.

Вариант 2. Использование современного синтаксиса (Async/Await)

Если ваша конфигурация работает на платформе версии 8.3.18 и выше, мы рекомендуем отказаться от цепочек ОписаниеОповещения в пользу оператора Ждать. Это значительно упрощает код и делает его линейным, что облегчает отладку в веб-клиенте.

Посмотрим на пример современного подхода:


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

Вариант 3. Перенос обработки на сторону сервера (Рекомендуемый)

Как показывает практика, работа с бинарными данными и потоками внутри браузера (особенно в устаревших версиях, таких как Internet Explorer) может быть нестабильной. Проанализируем ситуацию: если нам нужно всего 5 байт, не проще ли передать файл на сервер, где 1С обладает полным набором инструментов без ограничений браузера?

Алгоритм действий будет следующим:

  1. Используем метод НачатьПомещениеФайлаНаСервер (или ПоместитьФайлНаСерверАсинхронно).
  2. Браузер копирует файл во временное хранилище.
  3. На сервере получаем ДвоичныеДанные из этого хранилища.
  4. Используем объект ЧтениеДанных уже на сервере, где он работает мгновенно и без расширений.
  5. Возвращаем нужный результат (5 байт) обратно на клиент.

Этот способ является наиболее надежным, так как он обходит проблемы с совместимостью различных браузеров и нестабильностью JavaScript-движков при работе с типизированными массивами данных.

Важные замечания по безопасности и стабильности

При работе в веб-клиенте следует помнить о нескольких критических моментах:

Таким образом, мы выяснили, что чтение из файла в веб-клиенте — задача вполне решаемая. Главное — строго следовать асинхронной модели программирования 1С и не забывать про необходимость расширения работы с файлами для браузера.

← На главную