Многие разработчики делают AJAX в Битрикс через отдельные PHP-файлы или через роутинг ядра. Это работает, но есть правильный встроенный способ — через параметр ajaxMode и компонентный AJAX.
Способ 1: Стандартный ajaxMode
Простейший способ — передать параметр AJAX_MODE компоненту. Компонент перерисует только себя без перезагрузки страницы:
// В шаблоне страницы
$APPLICATION->IncludeComponent(
'company:catalog.list',
'',
[
'AJAX_MODE' => 'Y',
'AJAX_OPTION_JUMP' => 'N',
'AJAX_OPTION_STYLE' => 'Y',
'AJAX_OPTION_HISTORY'=> 'N',
]
);
При клике на пагинацию или фильтр страница обновит только блок компонента.
Способ 2: Ручной AJAX через action
Для сложных сценариев — собственный AJAX-обработчик прямо в компоненте:
// component.php
if ($this->request->isAjaxRequest()) {
$action = $this->request->get('action');
if ($action === 'load_more') {
$page = (int) $this->request->get('page');
$items = $this->loadItems($page);
$this->sendResponse([
'items' => $items,
'hasMore' => count($items) === $this->arParams['PAGE_SIZE'],
]);
}
}
// Вспомогательный метод
protected function sendResponse(array $data): void
{
header('Content-Type: application/json; charset=utf-8');
echo \Bitrix\Main\Web\Json::encode($data);
die();
}
JavaScript для отправки AJAX
// Правильный способ с CSRF-токеном Битрикс
async function loadMore(page) {
const response = await fetch(window.location.href, {
method: 'POST',
headers: {
'X-Bitrix-Csrf-Token': BX.message('bitrix_sessid'),
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
action: 'load_more',
page: page,
sessid: BX.message('bitrix_sessid'),
}),
});
const data = await response.json();
renderItems(data.items);
}
Способ 3: Через bitrix:ajax (BX.ajax)
BX.ajax.runComponentAction(
'company:catalog.list', // компонент
'loadMore', // метод экшена
{
mode: 'class',
data: { page: 2 },
}
).then(function(response) {
console.log(response.data);
});
Для этого в компоненте нужен класс с методами-экшенами:
// actions/LoadMore.php
namespace Company\CatalogList\Actions;
use Bitrix\Main\Engine\Action;
use Bitrix\Main\Engine\ActionFilter;
class LoadMore extends Action
{
public function configureActions(): array
{
return [
'loadMore' => [
'-prefilters' => [ActionFilter\Csrf::class],
],
];
}
public function loadMoreAction(int $page = 1): array
{
return ['items' => fetchItems($page)];
}
}
Защита AJAX-запросов
Всегда проверяйте сессию Битрикс:
if (!check_bitrix_sessid()) {
$this->sendResponse(['error' => 'Invalid session']);
}
// Или через D7
if (!\Bitrix\Main\Security\Random::validateToken($token)) {
throw new \Bitrix\Main\SystemException('Invalid CSRF token');
}
Итог
Используйте ajaxMode для простых случаев (пагинация, фильтры). Для сложной логики — компонентный AJAX с isAjaxRequest() и JSON-ответом. Не делайте отдельные PHP-файлы для AJAX — это антипаттерн который усложняет поддержку.
