В чем проблема с Ajax-запросами в 1С-Битрикс?

Как известно в версии 17.5.10 главного модуля 1С-Битрикс появились нативные обработчики ajax-запросов у компонентов и модулей. В чем же проблема?

В данной статье я буду обсуждать только ajax-запросы к компонентам, так как проблема именно с ними, а именно, вызов метода компонента происходит статически, и мы не получаем параметров вызова компонента $arParams. Понятно, что информацию можно передавать в параметрах запроса, но что если параметров очень много или в них содержатся какие-либо секретные данные?

В этой статье я попробовал ответить на этот вопрос и придумать решение.

Если Bitrix не дает нам $arParams, получим его самостоятельно.

Исходный код из примеров ниже на GitHub Gist: https://gist.github.com/pgooood/cd5169265e5abf4af02859d075dafe5d

Что необходимо чтобы получить $arParams не имея экземпляра класса компонента?

  1. Путь к PHP файлу, в котором происходит вызов компонента
  2. Идентификатор компонента в файле

Эти два параметра придется передать в ajax-запросе, если реальный путь к файлу на сервере — это секретная информация, можно его зашифровать, в своем решении я использую обычный Base64, как защиту от дурака.

Теперь мы имеем все необходимое чтобы достать $arParams. Что из инструментария битрикса нам понадобится:

  • метод CBitrixComponent::GetEditAreaId($entryId) — это единственный способ, из тех что я нашел, позволяющий получить идентификатор компонента в рамках файла скрипта, так как другие свойства класса CBitrixComponent, которые могли помочь, объявлены как приватные.
  • метод PHPParser::ParseScript($scriptContent)- позволяет распарсить содержимое PHP файла и получить информацию о находящихся в нем компонентах, в том числе и желанный$arParams.

Первое что мы сделаем — это класс компонента реализующий интерфейс Bitrix\Main\Engine\Contract\Controllable, в котором объявим обработчик аякс-запроса exampleRequest:

Далее добавим в класс метод, который будет получать уникальный идентификатор нашего компонента в файле:

Добавим методы для получения информации о компонентах из файла скрипта:

  • статический метод pageComponents, который будет возвращать все компоненты в заданном PHP файле, добавив в них идентификаторы, по которым мы сможем найти нужный
  • и статический метод componentData возвращающий информацию о компоненте по его идентификатору

Теперь добавим в $arResult необходимые данные: идентификатор компонента и путь к файлу скрипта, для этого изменим наш метод excecuteComponent следующим образом

в примере выше, мы предполагаем, что компонент вызывается в файле, который является точкой входа для http-запроса (например, /index.php), если компонент расположен в другом месте, например в шаблоне сайта, то для значения SCRIPT_PATH необходимо задать соответствующий путь.

Перейдем к шаблону компонента, там выполним аякс-запрос сразу при загрузке страницы, передав в качестве параметров запроса идентификатор компонента componentId и закодированный в Base64 путь к файлу скрипта scriptCast, при этом не забудем подключить аякс-библиотеку битрикса CJSCore::Init(['ajax']);, например в файле component_epilog.php

Чтобы обработать этот запрос и при этом получить исходный массив $arParams изменим метод exampleRequestAction в классе компонента следующим образом:

На этом все, еще раз ссылка на исходники: https://gist.github.com/pgooood/cd5169265e5abf4af02859d075dafe5d

See more about me and my projects on https://pgood.space

See more about me and my projects on https://pgood.space