Ajax в модуле для 1С-Битрикс

25.08.2020
На момент написания статьи, официальной документации очень не хватает, и данная реализация взаимодействия клиентской части с модулем посредством ajax во многом была собрана по крупицам из статей/форумов интернетов (источники описывали не весь механизм взаимодействия, поэтому появилась эта статья). Только дока по BX.ajax была доступна, но это не совсем то что нужно, потому что в этом случае:
  • необходимо самостоятельно следить за безопасностью
  • самому подключать ядро движка
  • при ajax запросах нужно указывать относительный адрес (в общем-то нормально, но ... можно лучше)

Подключение js

Внимание: для полноты картины (и правильной реализации) настоятельно рекомендую почитать этот раздел следующей статьи.

Необходимо зарегистрировать свое расширение и инициализировать его. Таким образом можно подключить не только js, но и другую статику.

Например так (php):

•••
php
CJSCore::RegisterExt("name_ex", ['js' => "/local/modules/module_dir/static/script.js"]); CUtil::InitJSCore(["name_ex"]);

Другой вопрос: где это сделать? В моем случае понадобилось подключать в обработчике события OnAdminContextMenuShow чтобы вывести на админ-панель дополнительные кнопки и прикрутить к ним логику.

Ajax запросы

Настройка среды модуля для выполнения ajax запросов происходит в несколько этапов.

Создать файл .settings.php в директории модуля со следующим содержимым:

•••
php
return [ 'controllers' => [ 'value' => [ 'namespaces' => [ /* название пространства имен, в котором расположены классы с action функциями => имя этого пространства имен на клиентской стороне (как из js обращаться к этому пространству имен) */ "\\namespace" => 'namespace', ], ], 'readonly' => true, ], ];

Затем в директории модуля необходимо создать директорию lib, а в ней php скрипт/скрипты где разместить указанное пространство имен. Размещать в lib обязательно, если разместить в корне то работать не будет :)

Есть возможность разместить все в глобальном пространстве имен (не знаю на сколько это правильно, но работает). Для этого вместо \\namespace нужно указать пустую строку.

В моем случае (для примера) я создал только один файл ajax.php.

Необходимо реализовать класс (нестатик), где методы с постфиксом Action будут доступны из js на стороне клиентской части (без учета регистра и без постфикса Action):

•••
php
//если не глобальное пространство имен, тогда надо указать //namespace namespace; //подключение пространства имен контроллера use Bitrix\Main\Engine\Controller; class ajax extends Controller { public function testAction() { //объект HttpRequest $oRequest = $this->getRequest(); return ["response" => "ok"]; } }

Документация по HttpRequest

Теперь этот метод можно вызвать на клиентской части через BX.ajax.runAction:

•••
php
BX.ajax.runAction( //вызываемый метод формата: partner:module_name.namespace.class_name.test 'partner:module_name.name.ajax.test', { //данные для пост запроса data: {param: 10} } ) .then(function(oResponse) { //код после получения данных от сервера, обьект ответа в oResponse });

Придет объект вида:
•••
js
{ status: "success", data: {/* то что вернул метод класса (ajax::testAction) */} errors: [] }