Выполнение AJAX запросов в WordPress

Категория: 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 разделитель параметров '&' не корректно кодируется, как '&amp;' функцией 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

категория: WordPress