Работа в веб-клиенте 1С:Предприятие на операционной системе macOS часто сопровождается трудностями, связанными с жесткой политикой безопасности Apple. Одной из самых распространенных проблем является сообщение: «Невозможно открыть файл, так как Apple не может проверить его на наличие вредоносного ПО». Это происходит из-за работы механизмов Gatekeeper и нотаризации приложений. В данной статье мы подробно разберем, как преодолеть эти ограничения, настроить систему и правильно написать код для работы с файлами в веб-интерфейсе.
Прежде чем переходить к коду, давайте проанализируем ситуацию. Когда мы пытаемся программно запустить файл из 1С в браузере (особенно в Safari или Chrome на Mac), операционная система помечает любой загруженный из сети файл специальным атрибутом «карантина» (com.apple.quarantine). Поскольку временный файл, созданный расширением 1С, не имеет цифровой подписи, одобренной Apple, система безопасности блокирует его выполнение.
Кроме того, современные браузеры работают в режиме «песочницы». Это означает, что команда ЗапуститьПриложение, которая привычно работает в тонком клиенте на Windows, в веб-клиенте на macOS может просто игнорироваться или вызывать ошибку доступа. Мы выясним, как обойти эти ограничения, используя асинхронные методы и правильные механизмы доставки данных на клиент.
Самый простой, но «ручной» способ — это разрешить запуск конкретного файла в настройках macOS. Рассмотрим этот алгоритм по шагам:
После этого система запомнит ваш выбор для этого конкретного файла или типа процесса, и запуск станет возможным. Однако для автоматизации работы пользователей этот способ не подходит, поэтому перейдем к программным методам.
Проанализируем ситуацию, когда нам нужно программно записать файл во временный каталог и запустить его. В macOS критически важно соблюдать стандарты POSIX для путей. Посмотрим на пример кода, который учитывает особенности веб-клиента и асинхронность платформы 1С.
Сначала подготовим файл на сервере и передадим его во временное хранилище:
&НаСервереБезКонтекста
Функция ПолучитьФайлНаСервере(ПутьКФайлу, Расширение)
// Генерируем уникальное имя во временном каталоге сервера
ВременныйФайл = ПолучитьИмяВременногоФайла(Расширение);
КопироватьФайл(ПутьКФайлу, ВременныйФайл);
// Читаем данные и помещаем в хранилище
Двоичные = Новый ДвоичныеДанные(ВременныйФайл);
Адрес = ПоместитьВоВременноеХранилище(Двоичные);
Возврат Адрес;
КонецФункции
Теперь рассмотрим клиентскую часть. Нам необходимо последовательно: подключить расширение работы с файлами, получить путь к локальному временному каталогу, записать туда данные и только потом попытаться их открыть.
&НаКлиенте
Процедура ПослеПодключенияРасширения(Результат, Дополнительно) Экспорт
Если Результат Тогда
// Запрашиваем каталог временных файлов асинхронно
НачатьПолучениеКаталогаВременныхФайлов(Новый ОписаниеОповещения("ПослеПолученияКаталога", ЭтотОбъект, Дополнительно));
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПослеПолученияКаталога(Результат, Дополнительно) Экспорт
// Важный нюанс для macOS: проверяем разделитель пути
Разделитель = "/";
ИмяФайла = "doc_" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss") + "." + Дополнительно.Расширение;
ПолныйПуть = Результат + (Прав(Результат, 1) = Разделитель ? "" : Разделитель) + ИмяФайла;
Дополнительно.Вставить("ИмяФайла", ПолныйПуть);
ДвоичныеДанные = Дополнительно.Данные;
// Записываем файл на диск клиента
ДвоичныеДанные.НачатьЗапись(Новый ОписаниеОповещения("ПослеЗаписиФайла", ЭтаФорма, Дополнительно), ПолныйПуть);
КонецПроцедуры
Важный момент: В macOS разделителем пути всегда является прямой слеш /. Как мы увидели в обсуждении, отсутствие проверки на завершающий слеш в пути, возвращаемом методом НачатьПолучениеКаталогаВременныхФайлов, часто приводит к ошибке «File not found», так как имя файла просто «склеивается» с именем папки.
Как показывает практика, попытки использовать НачатьЗапускПриложения в веб-клиенте под macOS часто блокируются самой «песочницей» браузера. Браузер считает выполнение локальных файлов небезопасным действием. Рассмотрим более стабильный подход, который использует стандартный механизм загрузки браузера.
Вместо того чтобы пытаться запустить файл командой ОС, мы предлагаем использовать метод ПолучитьФайл. В этом случае браузер сам скачивает файл, и пользователь может открыть его одним кликом из панели загрузок. Это обходит проверку Gatekeeper для программно запускаемых процессов.
&НаКлиенте
Процедура ОткрытьФайлДляВебКлиента(АдресХранилища, ИмяФайла)
// Параметр "Истина" во втором аргументе означает интерактивное скачивание
// В веб-клиенте это инициирует стандартный диалог или загрузку браузера
Оповещение = Новый ОписаниеОповещения("ПослеПолученияФайла", ЭтотОбъект);
ПараметрыПолучения = Новый ПараметрыПолученияФайла(Истина);
НачатьПолучениеФайлаССервера(Оповещение, АдресХранилища, ИмяФайла, ПараметрыПолучения);
КонецПроцедуры
Выясним причину, почему это работает лучше. Когда браузер (Chrome или Safari) скачивает файл через стандартный API, он помещает его в папку «Загрузки», к которой у пользователя есть явные права доступа. Файл при этом остается под защитой системы, но его открытие пользователем вручную воспринимается macOS как доверенное действие.
Проанализируем ключевые отличия, которые нужно учитывать разработчику 1С при поддержке пользователей на Mac:
/. Рекомендуется использовать функцию ПолучитьРазделительПути() для универсальности.Начать....ПолучитьФайл — наиболее стабильная альтернатива.Таким образом, мы рассмотрели комплексный подход к решению проблемы. Если ваша задача — обеспечить бесперебойную работу пользователей в веб-интерфейсе на macOS, старайтесь минимизировать использование прямых команд операционной системы и отдавайте предпочтение стандартным механизмам работы браузера с файлами. Это не только решит проблему с «вредоносным ПО», но и сделает ваше решение более кроссбраузерным.