Как сделать AJAX-контроллер в 1С-Битрикс через BX.ajax.runAction?

Как сделать AJAX-контроллер в 1С-Битрикс через BX.ajax.runAction?

Модуль в /local/modules готов, форма ждёт ответ без перезагрузки - а в консоли Invalid csrf token или Could not find description in DefaultController. На практике это самая частая проблема: AJAX не работает, потому что запрос ушёл не в тот transport. В документации три пути: BX.ajax, runAction и runComponentAction. Ниже - сквозной сценарий для 1С-Битрикс: Управление сайтом: D7-контроллер, configureActions и BX.ajax.runAction. После чек-листа POST вернёт JSON status success в Network.

AJAX в CMS - это запрос к серверу без перезагрузки страницы. Современный путь: класс в lib/Controller/ модуля наследует Bitrix\Main\Engine\Controller, метод заканчивается на Action, на фронте вызываете BX.ajax.runAction('vendor:module.controller.method'). Ядро само проверяет HTTP-метод, авторизацию и CSRF-токен sessid. Пустой prefilters в configureActions снимает всю защиту - для гостевой формы используйте -prefilters, а не пустой массив.

Речь про коробочную CMS на вашем сервере, не про облачный портал Bitrix24. Если модуль ещё не собран - начните с гайда по созданию модуля: без установленного пакета и include.php контроллер просто не найдётся.

Выберите transport: runAction, runComponentAction, REST или legacy ajax.php

Сравнение transport AJAX в Битрикс: runAction, runComponentAction, REST и legacy ajax.php

AJAX (асинхронный запрос) - когда браузер спрашивает сервер в фоне и обновляет только кусок страницы. В Битрикс для этого есть четыре подхода. Путают их чаще всего - отсюда и ошибка DefaultController, когда запрос уходит не туда.

Задача Инструмент Где код Фронт
Логика своего модуля: корзина, ЛК, API внутри сайта Engine\Controller + runAction lib/Controller/ в модуле (B69) BX.ajax.runAction('vendor:module.order.create')
Кнопка в шаблоне компонента Controllerable + runComponentAction class.php компонента BX.ajax.runComponentAction(...)
Интеграция с внешней системой по URL REST API, вебхуки rest, local/routes fetch к /rest/... - см. гайд по REST
Старый сниппет с prolog_before.php Отдельный ajax/handler.php Любая папка fetch или BX.ajax на свой URL

Для AJAX внутри компонента без выноса в модуль - создание своего компонента и runComponentAction. Для красивого URL API, а не кнопки на странице - REST и настройка ЧПУ, не дублируйте urlrewrite-гайд здесь.

Делайте: для формы в своём модуле берите Engine\Controller и runAction. Не делайте: не тащите REST-вебхук туда, где хватит runAction - лишний transport усложнит отладку.

Создайте каркас контроллера в lib/Controller/

Схема создания D7-контроллера в lib/Controller/ модуля Битрикс

Контроллер - PHP-класс, который принимает AJAX-запрос и отдаёт JSON. Ядро ищет его по строке vendor:module.controller.method: vendor - ID модуля до точки, module - имя после точки, controller - имя файла без Controller, method - имя метода без суффикса Action. Например, для mycompany.shop и класса Order с createAction строка будет mycompany.shop:order.create.

  1. Добавьте .settings.php в корень модуля с defaultNamespace - ядро поймёт, где искать классы.
  2. Создайте lib/Controller/Order.php с namespace Mycompany\Shop\Controller.
  3. Унаследуйте класс от \Bitrix\Main\Engine\Controller.
  4. Назовите публичный метод createAction - суффикс Action обязателен.
  5. Подключите модуль через Loader::includeModule перед тестом.
  6. Проверьте путь mycompany.shop:order.create для класса Order и метода createAction.
// .settings.php модуля mycompany.shop
return [
    'controllers' => [
        'value' => [
            'defaultNamespace' => '\\Mycompany\\Shop\\Controller',
        ],
        'readonly' => true,
    ],
];
namespace Mycompany\Shop\Controller;

use Bitrix\Main\Engine\Controller;

class Order extends Controller
{
    public function createAction(array $fields): array
    {
        return ['id' => 1, 'name' => $fields['name'] ?? ''];
    }
}

Типичная ошибка Could not find description of shop.order.create in DefaultController: нет .settings.php, класс лежит не в lib/Controller/, или MODULE_ID не совпадает с первой частью строки runAction.

Делайте: держите контроллеры только в lib/Controller/ с PSR-4. Не делайте: не кладите класс в корень модуля - резолвер уйдёт в DefaultController.

Настройте configureActions: prefilters, CSRF и гостевые POST

Чеклист configureActions: prefilters, CSRF и гостевые POST в Битрикс

configureActions - таблица правил для каждого экшена. По умолчанию ядро вешает три prefilters (предфильтры - проверки до выполнения метода): HttpMethod, Authentication, Csrf. CSRF (защита от подделки запроса) требует sessid в data POST-запроса.

use Bitrix\Main\Engine\ActionFilter\Authentication;
use Bitrix\Main\Engine\ActionFilter\Csrf;
use Bitrix\Main\Engine\ActionFilter\HttpMethod;

public function configureActions(): array
{
    return [
        'create' => [
            '-prefilters' => [Authentication::class],
            '+prefilters' => [
                new HttpMethod([HttpMethod::METHOD_POST]),
            ],
        ],
    ];
}

Ключ prefilters с пустым массивом полностью заменяет стандартные фильтры - CSRF и авторизация исчезнут. Для гостевой формы снимайте только Authentication через -prefilters, Csrf на POST оставляйте.

Ошибка Access denied - экшен требует авторизованного пользователя. Invalid csrf token - в data не передали sessid: BX.bitrix_sessid().

Делайте: для мутаций оставляйте POST и Csrf. Не делайте: не пишите prefilters => [] ради быстрого фикса - откроете дыру.

Вызовите экшен с фронта через BX.ajax.runAction

BX.ajax.runAction - JS-обёртка над /bitrix/services/main/ajax.php. Она сама подставляет action и при просрочке csrf обновляет токен.

BX.ajax.runAction('mycompany.shop.order.create', {
    data: {
        fields: { name: 'Тест' },
        sessid: BX.bitrix_sessid()
    }
}).then(function (response) {
    if (response.status === 'success') {
        console.log(response.data);
    } else {
        console.error(response.errors);
    }
});

В DevTools откройте Network, найдите ajax.php, проверьте Form Data: action=mycompany.shop.order.create, sessid совпадает с BX.bitrix_sessid(). Ответ: {"status":"success","data":{...},"errors":[]}. Ошибки в errors[].message - читайте code: invalid_csrf, ACCESS_DENIED.

На сервере для бизнес-ошибок используйте $this->addError(new Error('Текст', 'MY_CODE')) - фронт получит status error без PHP fatal.

Делайте: логируйте response.errors в консоль при отладке. Не делайте: не светите sessid в публичных логах.

Отладьте типичные ошибки в Network и консоли

Сообщение Причина Что сделать
Could not find description ... DefaultController Неверный namespace или путь класса .settings.php, lib/Controller/, includeModule
Invalid csrf token Нет sessid в POST data.sessid = BX.bitrix_sessid()
Access denied Authentication не снят для гостя -prefilters Authentication, Csrf оставить
Could not find value for parameter Имя поля в data не совпало с аргументом Action fields в data для array $fields

Legacy ajax.php с prolog_before.php и check_bitrix_sessid() работает, но каждый обработчик пишете вручную. Миграция: перенесите логику в *Action, замените fetch на runAction, удалите дублирующий handler.php.

Делайте: сверяйте строку action с MODULE_ID и именем класса. Не делайте: не смешивайте runAction и runComponentAction в одной кнопке без явного выбора.

Получите рабочий AJAX-экшен: чек-лист перед продом

  1. Убедитесь, что POST-мутации идут только через HttpMethod POST.
  2. Проверьте sessid в каждом POST с фронта.
  3. Настройте configureActions: гостю - только -Authentication, не пустой prefilters.
  4. Прогоните Network: status success и понятные errors[].code.
  5. Закройте права: гостевой экшен не должен вызывать админ-логику.
  6. Сохраните в репозитории .settings.php и тестовый вызов runAction - чтобы команда повторила сценарий без угадываний.

Workflow: кнопка на странице → BX.ajax.runAction → /bitrix/services/main/ajax.php → Order::createAction → JSON в браузер.

Нужен разбор AJAX под ваш модуль - напишите через контакты. Похожие кейсы - в портфолио.

Автор: Максим Мольков, разработчик 1С-Битрикс.
Источники: справка BX.ajax.runAction, пре- и постфильтры BitrixFramework, урок "Контроллер" (LESSON_ID=6436).

Частые вопросы

Чем runAction отличается от runComponentAction?

runAction вызывает Engine\Controller в модуле по строке vendor:module.controller.method. runComponentAction - экшены class.php компонента с Controllerable и signedParameters. Модульная логика - runAction, кнопка в шаблоне компонента - runComponentAction.

Зачем configureActions, если фильтры есть по умолчанию?

Дефолты подходят не всем: гостевая форма, только POST, отключение лишней проверки. configureActions задаёт правила точечно. Пустой prefilters снимает всё - используйте +prefilters и -prefilters.

Как убрать проверку CSRF для публичного AJAX?

Технически - снять Csrf через -prefilters, но для POST это дыра. Правильный путь: оставить Csrf и передавать sessid: BX.bitrix_sessid() в data. Снимать Csrf только для осознанных GET-чтений без мутаций.

Где физически лежит контроллер?

В /local/modules/vendor.module/lib/Controller/Имя.php. Namespace пропишите в .settings.php controllers.defaultNamespace. Без этого ядро ищет класс в DefaultController и падает с Could not find description.

Чем AJAX-контроллер отличается от REST API?

runAction - внутренний transport CMS для страниц сайта, endpoint ajax.php. REST - внешние интеграции по /rest/ с приложениями и вебхуками. Для кнопки в ЛК берите runAction, для CRM снаружи - REST из отдельного гайда.

Нужен ли local/routes для runAction?

Нет. runAction ходит в /bitrix/services/main/ajax.php. local/routes нужен для своих URL и REST-подобных маршрутов - это тема ЧПУ и urlrewrite, не базовый AJAX-экшен.

Читайте также

Интеграции с 1С и API
1073 6 мин.

Как настроить регистрацию и личный кабинет покупателя на 1С-Битрикс?

Пошаговая настройка регистрации на сайте битрикс: Главный модуль, main.register, system.auth.form и sale.personal.section с историей заказов и 152-ФЗ.
Интеграции с 1С и API
941 6 мин.

Как настроить скидки и промокоды на 1С-Битрикс: правила корзины и купоны

Пошаговый гайд по скидкам в CMS-магазине: скидка на товар, правило корзины от суммы, купоны с лимитом, приоритеты без конфликтов и тестовый заказ. Не Bitrix24.
Интеграции с 1С и API
757 15 мин.

Что такое компонент в Битриксе и как он работает

Каждый разработчик, впервые столкнувшийся с Битриксом, проходит через своеобразный обряд посвящения. Вначале кажется, что это просто CMS, где можно поправить HTML в визуальном редакторе или дописать пару строк CSS. Но однажды наступает момент, когда нужно изменить логику вывода новостей, отфильтровать товары по хитрому свойству или добавить на страницу нечто совершенно новое. И тут он впервые слышит это слово — «компонент». Для многих этот момент становится стеной. Система, казавшаяся понятной, вдруг превращается в черный ящик, полный непонятных файлов и странных переменных. Но стоит лишь раз заглянуть под капот, как эта стена рассыпается, превращаясь в набор удивительно логичных и мощных строительных блоков. Понимание компонентов — это тот самый щелчок, после которого разработка на Битрикс из мучения превращается в творчество.

Эта статья — ваш проводник в мир компонентов «1С-Битрикс». Мы не будем сыпать сухими терминами из документации. Вместо этого мы совершим путешествие: от философии, заложенной в эту архитектуру, до мельчайших деталей её работы. Мы разберем компонент на атомы — его файлы, логику, шаблон, параметры — и соберем обратно, чтобы вы не просто знали, что это, но и глубоко понимали, почему это работает именно так. Это знание — ключ к эффективной и профессиональной разработке на Битрикс.

Интеграции с 1С и API
714 2 мин.

Установка Composer в 1С-Битрикс

Установка Composer в проекте на 1С-Битрикс требует учета особенностей платформы, чтобы обеспечить корректную работу и интеграцию с системой.