Выполнение AJAX запросов в WordPress
Чтобы обработать любой AJAX запросов в WordPress нужно зарегистрировать функцию-обработчик этого запроса через специальный хук. Вы не сможете выполнить AJAX запрос просто создав PHP-скрипт в каталоге темы или плагина, нужно именно зарегистрировать обработчик! Запрос нужно отправлять по адресу /wp-admin/admin-ajax.php
и передавать в параметре action
название зарегистрированного вами обработчика.
Внимание!
Не регистрируйте обработчик в шаблоне - это не сработает!
Формирование запроса
1. Формируем ссылку на обработчик AJAX запросов и задаем имя зарегистрированного обработчика:
var url = '<?= admin_url('/admin-ajax.php?action=get_posts_html') ?>'
+ '&_wpnonce=<?= wp_create_nonce('get_posts_html') ?>';
Примечание
Параметр _wpnonce
будет содержать ключ (набор символов) проверки на стороне сервера, для предотвращения обработки запросов со сторонних источников.
2. Напишем экшн на стороне браузера (JavaScript) для подготовки и отправки запроса:
jQuery(function($) {
$('.btnLoadMorePosts').click(function(e) {
// Вы также можете установить имя обработчика и ключ в $_POST параметрах
var requestData = {
//action: 'get_posts_html',
//_wpnonce: '<?= wp_create_nonce('get_posts_html') ?>',
query_args: JSON.parse('<?= json_encode($query_args) ?>'),
my_other_params: {}
};
$.post(url, requestData, function(response) { // $.get OR $.post
console.log(response);
});
});
});
Обработка запроса
Регистрируем хук с именем обработчика запроса (get_posts_html
) в качестве суффикса:
add_action('wp_ajax_get_posts_html', 'get_posts_html_via_ajax');
add_action('wp_ajax_nopriv_get_posts_html', 'get_posts_html_via_ajax');
function get_posts_html_via_ajax() {
if (check_ajax_referer($_REQUEST['action']) !== 1 || wp_verify_nonce($_REQUEST['_wpnonce'], $_REQUEST['action']) !== 1) {
wp_send_json_error([
'message' => 'Ошибка! Запрос не разрешен.'
]);
}
ob_start();
// some action
$html = ob_get_clean();
wp_send_json_success([
'html' => $html,
'post_count' => 20
]);
header('Content-Type: application/json');
$response = [
'success' => true,
'data' => [
'html' => $html,
'post_count' => 20
]
];
echo json_encode($response);
die();
}
После регистрации обработчика, AJAX запрос по URL wp-admin/admin-ajax.php?action=get_posts_html
запустит обработчик wp_ajax_get_posts_html
.
Примечание
Префикс wp_ajax_
регистрирует AJAX обработчик для авторизированных пользователей, wp_ajax_nopriv_
регистрирует обработчик для неавторизированных посетителей.
Внимание!
Функция is_admin()
внутри AJAX обработчика всегда будет возвращать true
.
Обработка ошибок
Если обработчик запроса (action
) не зарегистрирован - WordPress возвращает код 0
, при непредвиденной ошибке -1
.
Безопасность
Проверяет откуда отправили запрос:
check_ajax_referer($action, $query_arg, $die);
Сгенерить токен:
$nonce = wp_create_nonce($action);
Сформировать токен и добавить его как параметр к заданному URL:
$url = admin_url('/admin-ajax.php?action=get_posts_html');
$url = wp_nonce_url($url, 'get_posts_html');
Использование wp_nonce_url() с GET параметрами
В функции wp_nonce_url()
URL разделитель параметров '&' не корректно кодируется, как '&' функцией esc_html()
. Поэтому, вы можете использовать wp_nonce_url()
только для URL'ов без параметров. Это не удобно, поскольку тот же action
придется подставлять после того, как будет добавлен _wpnonce
.
Вспомогательные функции
Остановить выполнение и показать ошибку:
wp_die($error, $title, $args = []);
WordPress рекомендует использовать wp_die()
в случае, если выполнение не должно продолжаться дальше. Но не стоит использовать эту ф-цию при любом удобном случае, вместо этого пытайтесь обработать ошибки более изящно и "без шума".
Сформировать ответ в формате JSON:
wp_send_json_success([
'html' => 'some content'
]);
Формат ответа:
{
success: true,
data: {
html: "some content"
}
}
Прочие ф-ции:
wp_json_encode($data, $options = 0, $depth = 512);
wp_send_json($response_mixed); // Send a JSON response back to an Ajax request.
wp_send_json_success($data_mixed);
wp_send_json_error($data_mixed);
#wordpress ajax, #wp register handler for ajax request