При разработке и адаптации дополнительных отчетов и обработок для сервиса 1С:Фреш разработчики часто сталкиваются с жесткими ограничениями платформы. Все внешние обработки в облаке запускаются сервером в безопасном режиме. Попытка выполнить привычные операции записи на диск или прямого обращения к файловой системе сервера приводит к ошибкам нарушения прав доступа. Разберем подробно, почему возникают эти ограничения и какими стандартными инструментами платформы 1С:Предприятие 8.3 можно решить задачу формирования и выгрузки файлов на рабочее место пользователя.
Проанализируем архитектуру облачного сервиса. В модели сервиса (SaaS) на одном сервере или кластере одновременно работают тысячи информационных баз различных абонентов. Для изоляции данных платформа вводит безопасный режим, блокирующий следующие операции на сервере:
ЗаписьXML.ОткрытьФайл(), ЗаписьТекста.Открыть() с указанием пути к файлу или конструктора Новый ДвоичныеДанные("C:\temp\file.txt") категорически запрещено.Новый COMОбъект и внешних компонент.ЗапуститьПриложение().HTTPСоединение, FTPСоединение или ИнтернетПочта без специального запроса прав у администратора сервиса.Важно понимать ключевую границу: безопасный режим сервера контролирует исполнение серверных процедур. Интерактивные действия на стороне тонкого или веб-клиента безопасным режимом сервера не блокируются. Следовательно, правильная стратегия заключается в формировании данных в оперативной памяти на стороне сервера и их последующей передаче клиенту для записи на диск.
Рассмотрим, как заменить запрещенный метод ЗаписьXML.ОткрытьФайл() на полностью легальную работу с оперативной памятью. Начиная с версии 8.3.9 в платформе появился объект ПотокВПамяти, который поддерживается большинством механизмов сериализации и потоковой записи.
Разберем пошаговый алгоритм:
ПотокВПамяти на сервере.ЗаписьXML) методом ОткрытьПоток(), передав туда созданный поток памяти.ЗакрытьИПолучитьДвоичныеДанные().Посмотрим на пример серверной функции:
&НаСервере
Функция СформироватьФайл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);
Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецФункции
После того как данные сформированы и помещены во временное хранилище на сервере, клиентское приложение должно сохранить их на локальный диск пользователя. Рассмотрим подробнее реализацию на клиенте с помощью асинхронных вызовов платформы.
Платформа 1С:Предприятие предоставляет для управляемых форм метод НачатьПолучениеФайлаССервера() (или более гибкий НачатьПолучениеФайлов()). Он одинаково корректно работает как в тонком клиенте, так и в браузере под веб-клиентом.
Посмотрим на пример клиентского кода:
&НаКлиенте
Процедура КомандаВыгрузить(Команда)
АдресФайла = СформироватьФайлXMLНаСервере();
Если ЗначениеЗаполнено(АдресФайла) Тогда
ИмяФайла = "export_data.xml";
ПараметрыПолучения = Новый ПараметрыПолученияФайлаССервера(АдресФайла, ИмяФайла);
// Открываем интерактивный диалог сохранения на клиенте
НачатьПолучениеФайлаССервера(ПараметрыПолучения);
КонецЕсли;
КонецПроцедуры
Если в конфигурации используется «Библиотека стандартных подсистем» (БСП), которая является базой для решений в 1С:Фреш, задачу интерактивного сохранения можно упростить с помощью вызова функции ФайловаяСистемаКлиент.СохранитьФайл(). Она автоматически обрабатывает специфику работы браузеров и мобильных клиентов, исключая необходимость писать низкоуровневые оповещения.
Иногда логика внешней обработки требует не просто отдать файл пользователю, а передать его на внешний сервер интеграции (по протоколам HTTP, HTTPS или FTP) или сохранить в специальный общий каталог. В безопасном режиме такие действия заблокированы платформой.
Разберем, как получить доступ к таким ресурсам легально в рамках облачного сервиса. Конфигурации для 1С:Фреш поддерживают расширения безопасного режима БСП. В модуле объекта внешней обработки в стандартной функции СведенияОВнешнейОбработке() разработчик объявляет список необходимых разрешений.
Посмотрим на пример объявления сетевого разрешения:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
ПараметрыРегистрации.Версия = "1.0.0.1";
ПараметрыРегистрации.БезопасныйРежим = Истина;
// Создаем список запрашиваемых разрешений
Разрешения = Новый Массив;
// Разрешение на сетевой доступ к внешнему веб-сервису
РазрешениеИнтернет = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеИнтернетРесурса(
"https",
"api.example.com",
443,
"Выгрузка данных во внешнюю аналитическую систему"
);
Разрешения.Добавить(РазрешениеИнтернет);
ПараметрыРегистрации.Вставить("Разрешения", Разрешения);
Возврат ПараметрыРегистрации;
КонецФункции
При добавлении обработки в сервис администратор сервиса или автоматический аудит поставщика проверяет список запрашиваемых прав. После подтверждения платформа генерирует для данной обработки персональный профиль безопасности, который точечно открывает сетевой шлюз только к указанному узлу и порту, сохраняя общую защищенность инфраструктуры.