AJAX (Asynchronous JavaScript And XML) — это способ обмениваться данными с сервером без перезагрузки страницы. В WordPress исторически используется точка входа admin-ajax.php; параллельно существует встроенный REST API.
TL;DR
- AJAX обновляет отдельные части страницы без перезагрузки.
- В WordPress есть два основных пути: admin-ajax.php и REST API. Первый использовался в давние времена, второй более современный и используется уже более 10 лет.
- Минимальный стек: wp_enqueue_script + wp_localize_script + обработчик wp_ajax_* + jQuery/fetch.
- Безопасность: nonce, проверка прав, очистка данных, JSON-ответы.
- Производительность: кэширование, уменьшение частоты Heartbeat, дебаунс/троттлинг.
- Отладка: DevTools Network, лог WP_DEBUG, профилировщики запросов.
Что такое AJAX и как он работает в WordPress
AJAX (Asynchronous JavaScript And XML) — это способ обмениваться данными с сервером без перезагрузки страницы. В браузере событие (клик/скролл/ввод) запускает асинхронный запрос, сервер возвращает данные (чаще JSON), а JavaScript обновляет DOM частично. В WordPress исторически используется точка входа admin-ajax.php; параллельно существует встроенный REST API.

AJAX vs REST API в WordPress
- admin-ajax.php — решение для админки, использовалось в старые времена. Минусы: сложнее кэшировать, отдельной точки расширения нет, высокая нагрузка при большом количестве запросов. Особенно плохо это сказывается при использовании на фронтенде за пределами админки.
- REST API — Современный подход для обмена данными между компонентами. Использует регистрацию маршрутов (routes) и авторизацию для защищённых операций.
Примеры работы с AJAX на сайте
1) Подключаем скрипт и пробрасываем данные в JS
// functions.php или файл плагина
function theme_enqueue_ajax() {
wp_enqueue_script(
'my-ajax',
get_template_directory_uri() . '/assets/js/my-ajax.js',
array('jquery'),
null,
true
);
wp_localize_script('my-ajax', 'MyAjax', array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('my_action_nonce'),
));
}
add_action('wp_enqueue_scripts', 'theme_enqueue_ajax');
2) Пишем PHP-обработчик
function my_action_handler() {
// Проверка nonce для защиты от CSRF
check_ajax_referer('my_action_nonce', 'nonce');
// При необходимости — проверка прав
// if ( ! current_user_can('read') ) {
// wp_send_json_error(array('message' => 'Forbidden'), 403);
// }
$term = isset($_POST['term']) ? sanitize_text_field(wp_unslash($_POST['term'])) : '';
// Пример: эмуляция запроса к БД/АПИ
$items = array('Первый', 'Второй', 'Третий');
$filtered = array_values(array_filter($items, function($i) use ($term){
return $term === '' || mb_stripos($i, $term) !== false;
}));
wp_send_json_success(array(
'items' => $filtered,
'count' => count($filtered),
));
}
add_action('wp_ajax_my_action', 'my_action_handler');
add_action('wp_ajax_nopriv_my_action', 'my_action_handler'); // Если обработчик доступен гостям
И простой HTML-шаблон:
<input id="search" type="text" placeholder="Фильтр" />
<button id="loadMore">Загрузить</button>
<div id="result"></div>
Альтернатива без jQuery:
const send = (q) => {
const body = new URLSearchParams({ action: 'my_action', nonce: MyAjax.nonce, term: q });
return fetch(MyAjax.ajaxUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
body
}).then(r => r.json());
};
Отладка admin-ajax.php и ускорение админки
- Включите логирование в wp-config.php:
define('WP_DEBUG', true); define('WP_DEBUG_LOG', true);. Проверьте журнал ошибок. - DevTools → Network: отфильтруйте запросы к admin-ajax.php, проверьте вкладки Timing и Payload. Долгие запросы — кандидаты на оптимизацию.
- Профилирование: используйте плагины для мониторинга запросов к БД и хуков, чтобы найти «тяжёлый» обработчик.
- Heartbeat API: уменьшите частоту, если наблюдается нагрузка в админке:
add_filter('heartbeat_settings', function($settings){
$settings['interval'] = 60; // по умолчанию ~15 сек
return $settings;
});
// Опционально отключить на фронтенде (осторожно: может повлиять на автосохранение/локи)
add_action('init', function(){
if (!is_admin()) { wp_deregister_script('heartbeat'); }
});
Безопасность AJAX
- CSRF: всегда используйте nonce (
wp_create_nonce,check_ajax_referer). - Права: проверяйте
current_user_can()для действий, доступных не всем. - Очистка данных:
sanitize_text_field,absint,sanitize_emailи т.д. - Ответы: отправляйте JSON через
wp_send_json_success/error, не выводите «лишний» HTML/echo до ответа. - XSS: экранируйте вывод на фронтенде, создавайте текстовые ноды или используйте безопасное кодирование.
Производительность и лучшие практики
- Кэшируйте результаты тяжёлых запросов (Transients, object cache):
$key = 'ajax_list_' . md5($term);
$data = get_transient($key);
if ($data === false) {
// $data = результат тяжёлого запроса
$data = array('a','b','c');
set_transient($key, $data, 5 * MINUTE_IN_SECONDS);
}
wp_send_json_success(array('items' => $data));
- Оптимизируйте частоту: дебаунс/троттлинг на фронтенде для событий ввода и скролла.
- Минимизируйте payload: передавайте только нужные поля; пагинируйте данные.
- Группируйте запросы: по возможности объединяйте несколько маленьких запросов в один.
- Для публичных GET: рассмотрите переход на REST API — он лучше кэшируется и масштабируется.
Типичные ошибки
- Забыли параметр
action— обработчик не сработает. - Не локализовали
ajaxUrl— фронтенд «не знает», куда отправлять запрос. - Нет хука
wp_ajax_nopriv_*для гостей — 0/403 в ответе. - Вывод до
wp_send_json_*— ломает JSON. - Истёкший nonce — периодические 403; регенерируйте nonce или обновляйте страницу/токен.
Итог
AJAX в WordPress — мощный инструмент для динамичных интерфейсов. Однако уже устарел и для новых проектов лучше переходите на REST API — так вы получите кэширование, масштабирование и более предсказуемую архитектуру.