AJAX в WordPress для начинающих
Что такое AJAX и зачем он нужен в WordPress?
AJAX (Asynchronous JavaScript and XML) — это технология, которая позволяет странице обмениваться данными с сервером без перезагрузки браузера. Пользователь нажимает кнопку, данные отправляются на сервер, сервер отвечает — и страница обновляется «на лету».
Примеры использования AJAX в WordPress:
- Фильтрация постов по категориям без перезагрузки
- Отправка формы обратной связи
- Подгрузка комментариев или постов («загрузить ещё»)
- Проверка доступности логина при регистрации
- Лайки, голосования, рейтинги
Как WordPress обрабатывает AJAX-запросы?
WordPress имеет встроенный механизм для работы с AJAX. Все запросы направляются на один единственный файл: /wp-admin/admin-ajax.php.
Ваш JavaScript отправляет запрос туда, а WordPress сам разбирается, какую PHP-функцию вызвать на основе параметра action.
Пошаговый пример: кнопка «Загрузить ещё посты»
Разберём полный рабочий пример — кнопка, которая подгружает дополнительные посты без перезагрузки страницы.
Шаг 1. Структура файлов
Поместите код в файл плагина или в «functions.php» вашей темы:
wp-content/
themes/
Папка вашей темы/
index.php ← HTML-разметка
functions.php ← PHP-код
js/
ajax-demo.js ← JavaScript-кодШаг 2. Подключаем JavaScript и передаём данные в него
Файл functions.php:
function my_enqueue_scripts() {
wp_enqueue_script(
'ajax-demo',
get_template_directory_uri() . '/js/ajax-demo.js',
[], // никаких зависимостей — чистый JS
'1.0',
true // подключить в footer
);
// Передаём URL и nonce в JavaScript
wp_localize_script('ajax-demo', 'myAjax', [
'url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('my_ajax_nonce'),
]);
}
add_action('wp_enqueue_scripts', 'my_enqueue_scripts');wp_localize_script создаёт глобальную JS-переменную myAjax с нужными данными. Это стандартный способ безопасно передать PHP-данные в JavaScript.
Шаг 3. Регистрируем AJAX-обработчик в PHP
Файл functions.php:
<?php
function my_load_more_posts() {
// Проверка безопасности
check_ajax_referer('my_ajax_nonce', 'nonce');
$page = isset($_POST['page']) ? (int) $_POST['page'] : 1;
$args = [
'post_type' => 'post',
'posts_per_page' => 3,
'paged' => $page,
];
$query = new WP_Query($args);
if ($query->have_posts()) {
ob_start(); // Начинаем буферизацию вывода
while ($query->have_posts()) {
$query->the_post();
?>
<article>
<h2><a href="<?php the_permalink() ?>"><?php the_title() ?></a></h2>
<p><?php the_excerpt() ?></p>
</article>
<?php
}
$html = ob_get_clean(); // Получаем буфер
wp_reset_postdata();
wp_send_json_success(['html' => $html]);
} else {
wp_send_json_error(['message' => 'Постов больше нет']);
}
}
// Для авторизованных пользователей
add_action('wp_ajax_load_more_posts', 'my_load_more_posts');
// Для гостей (неавторизованных)
add_action('wp_ajax_nopriv_load_more_posts', 'my_load_more_posts');
?>Обратите внимание на два хука:
wp_ajax_{action}— для авторизованных пользователейwp_ajax_nopriv_{action}— для гостей
Если нужно обрабатывать запросы от всех — добавляйте оба.
Шаг 4. Пишем JavaScript с Fetch API
Файл js/ajax-demo.js:
document.addEventListener('DOMContentLoaded', function () {
let currentPage = 1;
const button = document.getElementById('load-more-btn');
const container = document.getElementById('posts-container');
button.addEventListener('click', async function () {
currentPage++;
button.textContent = 'Загрузка...';
button.disabled = true;
// FormData удобно использовать: WordPress принимает данные как $_POST
const formData = new FormData();
formData.append('action', 'load_more_posts'); // имя хука без префикса wp_ajax_
formData.append('nonce', myAjax.nonce);
formData.append('page', currentPage);
try {
const response = await fetch(myAjax.url, {
method: 'POST',
body: formData,
});
// Проверяем, что сервер вернул корректный HTTP-статус
if (!response.ok) {
throw new Error(`Ошибка сервера: ${response.status}`);
}
const data = await response.json();
if (data.success) {
container.insertAdjacentHTML('beforeend', data.data.html);
button.textContent = 'Загрузить ещё';
button.disabled = false;
} else {
button.textContent = 'Постов больше нет';
// Оставляем кнопку заблокированной
}
} catch (error) {
console.error('Ошибка AJAX:', error);
button.textContent = 'Попробовать снова';
button.disabled = false;
}
});
});Разберём ключевые моменты кода:
DOMContentLoaded— ждём, пока страница загрузится, прежде чем искать элементыasync/await— современный синтаксис для работы с асинхронными операциями, делает код читаемымFormData— автоматически формирует тело POST-запроса в нужном формате; WordPress читает эти данные через$_POSTresponse.ok— проверяем HTTP-статус до парсинга JSON,fetchне выбрасывает ошибку при статусах 4xx/5xxtry/catch— перехватываем сетевые ошибки (нет интернета, сервер недоступен)
Шаг 5. HTML-разметка в шаблоне
Файл index.php:
<div id="posts-container">
<?php if(have_posts()): ?>
<?php while(have_posts()): the_post() ?>
<article>
<h2><a href="<?php the_permalink() ?>"><?php the_title() ?></a></h2>
<p><?php the_excerpt() ?></p>
</article>
<?php endwhile ?>
<?php endif ?>
</div>
<button id="load-more-btn">Загрузить ещё</button>Разбор ключевых концепций
Nonce — защита от подделки запросов
Nonce (number used once) — это одноразовый токен безопасности. Он защищает от CSRF-атак (когда злоумышленник заставляет браузер пользователя делать нежелательные запросы от его имени).
<? php
// Создание nonce (в PHP, при загрузке страницы)
$nonce = wp_create_nonce('my_ajax_nonce');
// Проверка nonce (в AJAX-обработчике)
check_ajax_referer('my_ajax_nonce', 'nonce');
?>Всегда используйте nonce в своих AJAX-запросах — это обязательная практика безопасности.
wp_send_json_success и wp_send_json_error
WordPress предоставляет удобные функции для отправки JSON-ответов:
<? php
// Успешный ответ — JS получит data.success === true
wp_send_json_success(['html' => '<p>Контент</p>']);
// Ответ с ошибкой — JS получит data.success === false
wp_send_json_error(['message' => 'Что-то пошло не так']);
?>Эти функции автоматически завершают выполнение PHP die(), что обязательно для AJAX в WordPress.
Структура ответа, которую вы получите в JavaScript:
// wp_send_json_success:
{ "success": true, "data": { "html": "..." } }
// wp_send_json_error:
{ "success": false, "data": { "message": "Постов больше нет" } }Параметр action
Параметр action в JavaScript-запросе должен точно совпадать с суффиксом в названии хука PHP:
// В JS:
formData.append('action', 'load_more_posts');<? php
// В PHP:
add_action('wp_ajax_load_more_posts', 'my_load_more_posts');
// ↑ это должно совпадать ↑
?>Почему fetch не выбрасывает ошибку при 4xx/5xx?
Это частое заблуждение. В отличие от старого XMLHttpRequest, fetch считает запрос успешным, если он вообще дошёл до сервера — даже если сервер ответил ошибкой 404 или 500. Поэтому всегда проверяйте response.ok:
const response = await fetch(url, { method: 'POST', body: formData });
if (!response.ok) {
// Сервер вернул 4xx или 5xx — это ошибка
throw new Error(`HTTP ошибка: ${response.status}`);
}
const data = await response.json(); // Только теперь парсимИтог
Работа с AJAX в WordPress строится по простой схеме:
- JavaScript собирает данные в
FormDataи отправляет POST-запрос черезfetchна admin-ajax.php с параметромaction - WordPress находит зарегистрированный хук
wp_ajax_{action}и вызывает вашу PHP-функцию - PHP-функция обрабатывает запрос и возвращает JSON через
wp_send_json_success()илиwp_send_json_error() - JavaScript получает ответ, проверяет
data.successи обновляет страницу
Придерживайтесь четырёх правил: всегда используйте nonce, не забывайте добавлять nopriv-хук для гостей, всегда завершайте PHP-функцию через wp_send_json_*, и проверяйте response.ok перед парсингом JSON. Этого достаточно, чтобы безопасно и правильно работать с AJAX в любом WordPress-проекте.
коментарии