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

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

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

Почему стандартные методы выгрузки вызывают ошибку

Проанализируем архитектуру облачного сервиса. В модели сервиса (SaaS) на одном сервере или кластере одновременно работают тысячи информационных баз различных абонентов. Для изоляции данных платформа вводит безопасный режим, блокирующий следующие операции на сервере:

  1. Прямое обращение к физической файловой системе хоста (дискам сервера). Использование методов вроде ЗаписьXML.ОткрытьФайл(), ЗаписьТекста.Открыть() с указанием пути к файлу или конструктора Новый ДвоичныеДанные("C:\temp\file.txt") категорически запрещено.
  2. Инициализация COM-объектов через Новый COMОбъект и внешних компонент.
  3. Запуск внешних процессов с помощью команды ЗапуститьПриложение().
  4. Прямые сетевые вызовы через HTTPСоединение, FTPСоединение или ИнтернетПочта без специального запроса прав у администратора сервиса.

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

Способ 1. Формирование файлов в памяти через ПотокВПамяти и ЗаписьXML

Рассмотрим, как заменить запрещенный метод ЗаписьXML.ОткрытьФайл() на полностью легальную работу с оперативной памятью. Начиная с версии 8.3.9 в платформе появился объект ПотокВПамяти, который поддерживается большинством механизмов сериализации и потоковой записи.

Разберем пошаговый алгоритм:

  1. Создаем объект ПотокВПамяти на сервере.
  2. Инициализируем объект записи (например, ЗаписьXML) методом ОткрытьПоток(), передав туда созданный поток памяти.
  3. Записываем структуру данных.
  4. Закрываем объект записи и извлекаем из потока двоичные данные методом ЗакрытьИПолучитьДвоичныеДанные().
  5. Помещаем полученные двоичные данные во временное хранилище и возвращаем полученный адрес на клиент.

Посмотрим на пример серверной функции:


&НаСервере
Функция СформироватьФайлXMLНаСервере()
    
    // Создаем поток в оперативной памяти без обращения к файловой системе сервера
    ПотокПамяти = Новый ПотокВПамяти();
    
    ЗаписьXML = Новый ЗаписьXML();
    ЗаписьXML.ОткрытьПоток(ПотокПамяти, "UTF-8");
    
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    ЗаписьXML.ЗаписатьНачалоЭлемента("ВыгрузкаДанных");
    ЗаписьXML.ЗаписатьАтрибут("Версия", "1.0");
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("Данные");
    ЗаписьXML.ЗаписатьТекст("Тестовая выгрузка без обращения к дискам");
    ЗаписьXML.ЗаписатьКонецЭлемента();
    
    ЗаписьXML.ЗаписатьКонецЭлемента();
    ЗаписьXML.Закрыть();
    
    // Получаем двоичные данные из потока памяти
    ДвоичныеДанные = ПотокПамяти.ЗакрытьИПолучитьДвоичныеДанные();
    
    // Помещаем результат во временное хранилище текущей формы
    Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
    
КонецФункции

Если требуется сформировать простой текстовый файл или строку XML небольшого объема, можно воспользоваться методом УстановитьСтроку() объекта ЗаписьXML:


&НаСервере
Функция СформироватьСтрокуXML()
    
    ЗаписьXML = Новый ЗаписьXML();
    ЗаписьXML.УстановитьСтроку("UTF-8");
    
    ЗаписьXML.ЗаписатьНачалоЭлемента("КорневойЭлемент");
    ЗаписьXML.ЗаписатьТекст("Пример строки");
    ЗаписьXML.ЗаписатьКонецЭлемента();
    
    СтрокаXML = ЗаписьXML.Закрыть();
    ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(СтрокаXML);
    
    Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
    
КонецФункции

Способ 2. Получение и сохранение файла на стороне клиента

После того как данные сформированы и помещены во временное хранилище на сервере, клиентское приложение должно сохранить их на локальный диск пользователя. Рассмотрим подробнее реализацию на клиенте с помощью асинхронных вызовов платформы.

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

Посмотрим на пример клиентского кода:


&НаКлиенте
Процедура КомандаВыгрузить(Команда)
    
    АдресФайла = СформироватьФайлXMLНаСервере();
    
    Если ЗначениеЗаполнено(АдресФайла) Тогда
        
        ИмяФайла = "export_data.xml";
        ПараметрыПолучения = Новый ПараметрыПолученияФайлаССервера(АдресФайла, ИмяФайла);
        
        // Открываем интерактивный диалог сохранения на клиенте
        НачатьПолучениеФайлаССервера(ПараметрыПолучения);
        
    КонецЕсли;
    
КонецПроцедуры

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

Способ 3. Запрос разрешений профиля безопасности (БСП)

Иногда логика внешней обработки требует не просто отдать файл пользователю, а передать его на внешний сервер интеграции (по протоколам HTTP, HTTPS или FTP) или сохранить в специальный общий каталог. В безопасном режиме такие действия заблокированы платформой.

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

Посмотрим на пример объявления сетевого разрешения:


Функция СведенияОВнешнейОбработке() Экспорт
    
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
    ПараметрыРегистрации.Версия = "1.0.0.1";
    ПараметрыРегистрации.БезопасныйРежим = Истина;
    
    // Создаем список запрашиваемых разрешений
    Разрешения = Новый Массив;
    
    // Разрешение на сетевой доступ к внешнему веб-сервису
    РазрешениеИнтернет = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеИнтернетРесурса(
        "https", 
        "api.example.com", 
        443, 
        "Выгрузка данных во внешнюю аналитическую систему"
    );
    Разрешения.Добавить(РазрешениеИнтернет);
    
    ПараметрыРегистрации.Вставить("Разрешения", Разрешения);
    
    Возврат ПараметрыРегистрации;
    
КонецФункции

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

← На главную