При разработке под веб-клиент 1С программисты часто сталкиваются с тем, что код, который отлично работает в тонком клиенте, начинает выдавать ошибки в браузере. Наиболее частые из них касаются работы с файловой системой и JSON. В тонком клиенте платформа берет многое на себя, но веб-клиент накладывает строгие ограничения безопасности браузеров. Давайте разберем по шагам, как правильно адаптировать код для работы в вебе.
Рассмотрим классическую ситуацию: по нажатию кнопки в документе пользователю должен открываться Word-документ (например, инструкция). Разработчик пишет код, но получает ошибку: «Ошибка при вызове метода контекста (КаталогВременныхФайловАсинх)» или «Расширение для работы с файлами не подключено».
Проанализируем причину. В старых версиях 1С работа с файлами была синхронной, но современные браузеры отказались от технологии NPAPI, и теперь работа с файлами требует обязательной установки расширения для браузера («Расширение для работы с 1С:Предприятием»). Кроме того, методы проверки и подключения расширения, такие как НачатьПодключениеРасширенияРаботыСФайлами, являются асинхронными.
Если мы вызовем метод подключения и сразу же попытаемся получить временный каталог через КаталогВременныхФайловАсинх, код не остановится для ожидания подключения. Платформа попытается выполнить следующую строку, в то время как расширение еще не инициализировано, что и приведет к ошибке.
Как это решить: Перенесем код, зависящий от подключения, в отдельный метод, который будет вызываться только после успешного завершения асинхронного подключения.
&НаКлиенте
Процедура Расш1_СправкаСотруднику(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеПодключенияРасширения", ЭтотОбъект);
НачатьПодключениеРасширенияРаботыСФайлами(Оповещение);
КонецПроцедуры
&НаКлиенте
Асинх Процедура ПослеПодключенияРасширения(Подключено, ДополнительныеПараметры) Экспорт
Если Подключено Тогда
// Здесь размещаем код работы с файлами
Иначе
// Обработка ситуации, когда расширение не подключено
КонецЕсли;
КонецПроцедуры
Посмотрим на следующую частую ошибку. Разработчик, используя новые методы, пишет такой код:
Обещание = КаталогВременныхФайловАсинх + "Инструкция.docx";
ИмяФайла = Ждать Обещание;
При выполнении этого кода появляется ошибка преобразования к числу. Выясним причину. С версии платформы 1С 8.3.18 был введен новый тип данных — Обещание (Promise). Асинхронная функция КаталогВременныхФайловАсинх не возвращает строку с путем сразу, она возвращает именно Обещание. Мы не можем прибавить к объекту «Обещание» строковое имя файла напрямую.
Сначала необходимо извлечь результат из обещания с помощью оператора Ждать, получить путь к каталогу в виде строки, и только затем прибавлять к нему имя файла.
Рассмотрим правильный вариант реализации:
// Получаем обещание
Обещание = КаталогВременныхФайловАсинх;
// Ждем завершения асинхронной операции и получаем строку с путем
ИмяКаталога = Ждать Обещание;
// Формируем итоговый путь к файлу
ИмяФайла = ИмяКаталога + "Инструкция.docx";
// Продолжаем работу с файлом, например записываем данные
ДД.НачатьЗапись(ОписаниеОповещения, ИмяФайла);
Посмотрим на еще одну распространенную ошибку. При открытии документа в веб-клиенте может появляться сообщение: Процедура или функция с указанным именем не определена (ЗаписатьJSON).
Разберем, почему так происходит. Исторически глобальные методы ЗаписатьJSON, ПрочитатьJSON, а также объекты ЗаписьJSON и ЧтениеJSON недоступны на клиенте в веб-интерфейсе. Платформа 1С просто не транслирует их в JavaScript для браузера. В тонком клиенте они работают отлично, но при запуске в браузере возникает ошибка.
У нас есть два способа решения этой задачи в зависимости от версии используемой платформы:
Любую работу с JSON необходимо выносить на сервер. Если вам нужно сериализовать структуру или массив, используйте директивы компиляции. Формирование и чтение JSON должно происходить исключительно в процедурах с директивой &НаСервере или &НаСервереБезКонтекста.
&НаКлиенте
Функция СериализоватьВJSONКлиент(Объект)
// Вызываем серверную функцию для работы с JSON
Возврат СериализоватьВJSONНаСервере(Объект);
КонецФункции
&НаСервереБезКонтекста
Функция СериализоватьВJSONНаСервере(СериализуемыйОбъект)
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку;
ЗаписатьJSON(ЗаписьJSON, СериализуемыйОбъект);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
Фирма «1С» добавила новые глобальные методы — ЗаписатьЗначениеJSON() и ПрочитатьЗначениеJSON(). Их главная особенность в том, что они полностью доступны во всех клиентах, включая веб-клиент. Вам больше не нужно делать постоянные серверные вызовы ради простой конвертации структуры в строку.
Используя эти подходы, вы сможете корректно выстроить асинхронную логику работы с файлами и избежать ограничений веб-клиента при обработке JSON-данных.