Публикация информационной базы 1С на веб-сервере (под управлением IIS или Apache) — это отличный способ предоставить пользователям удобный доступ к системе через обычный интернет-браузер. Однако в процессе первой публикации разработчики часто сталкиваются со специфическими ошибками, которые не возникали при тестировании в тонком или толстом клиенте. В рамках данной статьи мы подробно разберем две критические проблемы, упомянутые в обсуждении: ошибку инициализации параметров сеанса на клиенте и неработоспособность «Универсального отчета» в веб-интерфейсе.
Рассмотрим ситуацию, когда сразу после ввода логина и пароля в окне браузера система выдает ошибку, указывающую на строку кода:
глПроверитьЗначение(ПараметрыСеанса.ТекстОшибки, СокрЛП(ВхТекстОшибки));
Выясним причину этого сбоя. Объект ПараметрыСеанса предназначен для хранения глобальных данных текущего сеанса пользователя на стороне сервера. Согласно официальной документации платформы 1С, данный объект имеет строго ограниченную область доступности:
Когда веб-клиент (выполняющийся непосредственно в браузере пользователя в виде JavaScript-кода) пытается напрямую обратиться к ПараметрыСеанса, платформа выбрасывает исключение, поскольку в клиентском контексте этой переменной просто не существует.
В ходе обсуждения автор темы сообщил, что проблема решилась установкой галочки «Внешнее соединение» в свойствах общего модуля. Проанализируем, почему это решение является иллюзорным и небезопасным.
Установка флага «Внешнее соединение» лишь разрешает компиляцию кода модуля при подключении к базе через COM-соединение. Если этот же общий модуль имеет включенный флаг «Клиент (управляемое приложение)» и вызывается из браузера, то обращение к ПараметрыСеанса.ТекстОшибки на клиенте все равно рано или поздно приведет к аварийному завершению работы веб-клиента. Скорее всего, в процессе тестирования автора вызов процедуры временно сместился в серверный контекст, либо конфигурация была запущена в режиме, отличном от чистого веб-клиента.
Для того чтобы код работал стабильно во всех режимах запуска, необходимо использовать один из следующих подходов.
Вариант 1. Использование инструкций препроцессора (экранирование кода)
Если общий модуль предназначен для работы в различных контекстах, код, обращающийся к серверным объектам, должен быть жестко ограничен инструкциями препроцессора. Разберем пример реализации:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
глПроверитьЗначение(ПараметрыСеанса.ТекстОшибки, СокрЛП(ВхТекстОшибки));
#КонецЕсли
В этом случае компилятор веб-клиента просто проигнорирует данную строку кода, что предотвратит возникновение синтаксических и runtime-ошибок в браузере.
Вариант 2. Вынос логики на сервер (Server Call)
Если веб-клиенту критически необходимо получить значение из параметров сеанса, напрямую обращаться к ним нельзя. Мы должны создать специальный общий модуль (например, с именем ОбщегоНазначенияВызовСервера) со следующими свойствами:
Внутри этого модуля создадим экспортную функцию, которая будет считывать параметр на сервере и возвращать его на клиент:
Функция ПолучитьТекстОшибкиИзСеанса() Экспорт
Возврат ПараметрыСеанса.ТекстОшибки;
КонецФункции
Теперь на стороне веб-клиента мы можем безопасно вызвать эту функцию:
ТекстОшибкиСеанса = ОбщегоНазначенияВызовСервера.ПолучитьТекстОшибкиИзСеанса();
глПроверитьЗначение(ТекстОшибкиСеанса, СокрЛП(ВхТекстОшибки));
Вариант 3. Однократное кэширование на клиенте при запуске
Поскольку каждое обращение к серверу через веб-клиент генерирует HTTP-запрос и снижает общую производительность системы, рекомендуется кэшировать часто используемые параметры сеанса (например, текущего пользователя или его настройки) в модуле управляемого приложения при начале работы системы, сохраняя их в глобальные переменные клиента.
---
Второй вопрос автора касается ситуации, когда отчет, построенный на базе Системы компоновки данных (СКД), успешно формируется в браузере, в то время как «Универсальный отчет» не выводит данные или вообще не открывается. Проанализируем технические причины этого поведения.
В старых конфигурациях или самописных базах «Универсальный отчет» представляет собой обработку, построенную на обычных формах. Платформа 1С:Предприятие в режиме веб-клиента принципиально не способна отображать обычные формы, так как они используют механизмы рендеринга операционной системы Windows (Win32 API) и ActiveX, недоступные в веб-браузерах.
Почему при этом работает СКД: Схема компоновки данных является декларативным описанием структуры отчета. Если у отчета на базе СКД отсутствует жестко привязанная форма (или создана управляемая форма), платформа 1С автоматически генерирует интерфейс управляемой формы «на лету». Этот автогенерируемый интерфейс полностью адаптирован под веб-клиент и прекрасно рендерится в браузере в виде HTML и CSS.
В коде старых версий «Универсального отчета» часто встречаются синхронные модальные вызовы интерактивных функций, такие как:
Предупреждение()Вопрос()ДиалогВыбораФайла()Современные веб-браузеры в целях безопасности блокируют любые попытки выполнения синхронного JavaScript-кода, останавливающего поток выполнения. Если в коде отчета присутствует такой метод, веб-клиент аварийно прекратит работу программы.
Для корректной работы в веб-интерфейсе весь интерактивный код должен быть переписан с использованием асинхронных аналогов. Рассмотрим пример адаптации кода:
Было (не работает в веб-клиенте):
Предупреждение("Отчет сформирован успешно!");
Стало (работает везде):
ПоказатьПредупреждение(Новый ОписаниеОповещения, "Отчет сформирован успешно!");
«Универсальный отчет» по умолчанию выводит детальные записи с большим количеством группировок, что приводит к генерации табличных документов колоссального объема. При работе через веб-клиент передача таких данных осуществляется порциями по протоколу HTTP.
Если размер отчета превышает лимиты веб-сервера (например, настройки LimitRequestBody в Apache или maxAllowedContentLength в IIS), веб-сервер вернет ошибку (например, HTTP: Expectation failed 417 или 500 Internal Server Error), и отчет не будет выведен на экран.
Для исправления работы отчетов в веб-интерфейсе рекомендуем выполнить следующие шаги: