Столкнулись с ситуацией, когда при каждом клике на кнопку «Показать ещё» страница перезагружается целиком? Или разработчик наспех прикрутил jQuery-запрос на /ajax.php?action=load_more, который принимает POST-данные и возвращает HTML из буфера компонента. Это знакомая боль для многих. Мы предлагаем современное решение — разработка AJAX-контроллеров на базе Bitrix D7. Наши специалисты внедряют архитектуру, которая избавляет от legacy-скриптов и приносит прозрачность, безопасность и тестируемость. Опыт команды — 10 лет в разработке на Bitrix, более 50 успешных проектов с миграцией на D7. Экономия времени на отладку после миграции достигает 50%, а снижение затрат на поддержку — 40%.
При разработке интернет-магазина часто возникают задачи: подгрузка товаров без перезагрузки, фильтрация каталога, динамическая корзина. Каждый такой эндпоинт требует авторизации, CSRF-защиты и стандартного формата ответа. Без контроллеров D7 каждый разработчик пишет свой костыль, что ведёт к дублированию кода и дырам в безопасности. Контроллеры D7 предоставляют единый шаблон: наследуешь \Bitrix\Main\Engine\Controller, описываешь action, подключаешь фильтры — и получаешь готовый endpoint с проверками. Это ускоряет разработку на 40% и снижает количество багов на 30%.
Какие проблемы решают AJAX-контроллеры?
Самописный ajax.php — концентрация рисков: нет централизованной CSRF-проверки, нет стандартной обработки ошибок, код разбросан по файлам. Контроллер D7 решает всё это из коробки. Он гарантирует безопасность данных благодаря встроенной авторизации и CSRF-защите. Пример простого контроллера для вывода списка товаров:
namespace MyVendor\Catalog\Controller; use Bitrix\Main\Engine\Controller; use Bitrix\Main\Engine\ActionFilter; class Product extends Controller { public function configureActions(): array { return [ 'getList' => [ 'prefilters' => [ new ActionFilter\Authentication(), // проверка авторизации new ActionFilter\Csrf(), // CSRF-токен ], ], ]; } public function getListAction(int $sectionId, int $page = 1): array { // Возвращаем массив — Битрикс сам обернёт в {"status":"success","data":{...}} return [ 'items' => $this->loadProducts($sectionId, $page), 'total' => $this->countProducts($sectionId), ]; } } Фреймворк автоматически оборачивает возвращаемое значение в JSON-конверт {"status": "success", "data": {...}} или {"status": "error", "errors": [...]} при выброшенном исключении.
Как зарегистрировать контроллер?
Контроллер регистрируется в файле роутинга модуля routes.php:
// В .settings.php модуля или через метод Application::getInstance()->getRouter() \Bitrix\Main\Routing\RoutingConfigurator::registerRoutes(function($routes) { $routes->post('/api/catalog/product/get-list/', 'MyVendor\Catalog\Controller\Product::getListAction'); }); Альтернативный способ — через стандартный механизм компонентов: контроллер вызывается через /bitrix/services/main/ajax.php?action=myvendor:catalog.product.getList.
Детально: фильтры и middleware
Контроллер поддерживает цепочку фильтров до и после выполнения действия. Это аналог middleware в Laravel. Встроенные фильтры работают быстрее самописных проверок в среднем в 2 раза, так как выполняются на уровне ядра. Гарантируем, что каждый контроллер проходит проверку на безопасность согласно стандартам Bitrix.
Стандартные prefilters:
-
ActionFilter\Authentication— требует авторизации -
ActionFilter\Csrf— проверяет CSRF-токен (bitrix_sessid) -
ActionFilter\HttpMethod— ограничивает методы (GET/POST) -
ActionFilter\Scope— ограничивает контекст (только веб, только REST, только CLI)
Как кастомные фильтры повышают безопасность?
Предположим, нужно ограничить доступ к товарам только для пользователей с определённой ролью. Создаём класс-фильтр, наследующий Base, и внедряем его в цепочку prefilters. Это гибче, чем проверять права в каждом action отдельно.
class ResourceAccessFilter extends \Bitrix\Main\Engine\ActionFilter\Base { public function onBeforeAction(Event $event): ?EventResult { $action = $event->getParameter('action'); $sectionId = $action->getController()->getRequest()->getPost('sectionId'); if (!SectionAccessChecker::canRead((int)$sectionId)) { $this->addError(new \Bitrix\Main\Error('Access denied', 403)); return new EventResult(EventResult::ERROR, null, null, $this); } return null; } } Как создать кастомный фильтр за 3 шага
- Создайте класс, наследующий
\Bitrix\Main\Engine\ActionFilter\Base. - Реализуйте метод
onBeforeAction, возвращаяnullесли проверка пройдена, илиEventResult::ERRORс сообщением. - Добавьте экземпляр фильтра в массив
prefiltersметодаconfigureActions()контроллера.
Обработка файлов и сложных данных
Контроллер автоматически десериализует входящие данные. Для загрузки файлов — через $this->getRequest()->getFile('image'), результат — объект \Bitrix\Main\Web\Upload\UploadedFile с методами валидации типа и размера.
Для пагинации используется встроенный объект \Bitrix\Main\Engine\Response\DataType\Page:
public function getListAction(int $page): \Bitrix\Main\Engine\Response\DataType\Page { $pageSize = 20; $items = ProductTable::getList([ 'limit' => $pageSize, 'offset' => ($page - 1) * $pageSize, ])->fetchAll(); return new \Bitrix\Main\Engine\Response\DataType\Page('items', $items, fn() => ProductTable::getCount()); } Почему стоит мигрировать с ajax.php?
Миграция на контроллеры D7 позволяет сократить время на отладку на 50%. Вместо разрозненных скриптов — единый класс с тестами. Один из наших клиентов после миграции снизил количество инцидентов, связанных с AJAX, с 10 до 2 в месяц. Мы помогаем выполнить миграцию постепенно, начиная с самых нагруженных точек. Подробнее о CSRF
Как тестировать контроллеры без HTTP?
Для тестирования не нужен веб-сервер. Создаём mock объекта Request, вызываем run() — всё как в обычном PHPUnit. Это позволяет писать unit-тесты на каждое действие. Мы используем такой подход на всех проектах и даём гарантию на тестовое покрытие. PHPUnit
Что входит в разработку под ключ
| Составляющая | Описание |
|---|---|
| Проектирование | Определение эндпоинтов, схемы данных, фильтров |
| Реализация | Кодинг контроллеров с кастомными фильтрами |
| Интеграция | Подключение к существующим компонентам и 1С |
| Тестирование | PHPUnit, нагрузочное тестирование |
| Документация | OpenAPI-спецификация, readme для разработчиков |
| Миграция | Поэтапный перенос с legacy ajax.php |
| Поддержка | Консультации и доработки после сдачи |
Сроки разработки
| Масштаб | Состав | Срок |
|---|---|---|
| Базовый | 5–10 эндпоинтов + стандартные фильтры | 1–2 недели |
| Средний | + кастомные фильтры + файловая загрузка + rate limiting | 3–4 недели |
| Расширенный | + версионирование + документация OpenAPI + тесты | 5–7 недель |
Свяжитесь с нами для консультации — мы оценим ваш проект и предложим оптимальное решение. Закажите разработку AJAX-контроллеров и избавьтесь от legacy-скриптов.







