Делаем WordPress Ajax запросы безопасно и правильно

Делаем WordPress Ajax запросы безопасно и правильно

· JavaScript и WordPress · 5 мин чтения

WordPress безумными темпами развивается и предоставляем больше и больше возможностей для разработчиков. Одна из них — это WordPress Ajax запросы, которые можно делать для авторизованных или неавторизованных пользователей.

Когда это можно пригодиться? Например, если вы хотите сделать форму обратной связи в модальном окне и не хотите, чтобы страница обновлялась. В данном случае вам нужно использовать Ajax.

Если вы просто сделаете Ajax и создадите файл, который будет это все обрабатывать, то это самое худшее, что можно сделать при работе с WordPress. Это не безопасно и ломает всю логику разработки.

Правильный способ

Для начала вам нужно создать Ajax запрос. Это можно сделать с помощью jQuery следующим способом:

<script type="text/javascript" >
jQuery(document).ready(function($) {

    var data = {
        action: 'ACTION_NAME',
        first_name: 'Ivan',
        last_name: 'Ivanov',
        _ajax_nonce: '<?php echo wp_create_nonce( 'my_ajax_nonce' ); ?>'
    };

    // начиная с 2.8 ajaxurl всегда определяется в admin-ajax.php
    // Если вам нужно, чтобы это работало на внешней стороне сайта для гостей и обычных пользователей, тогда удалите комментарий ниже:
    // var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
    jQuery.post(ajaxurl, data, function(response) {
        alert('Ответ сервера: ' + response);
    });
});
</script>

Вы можете добавить jQuery код в любой файл в WordPress, но это не будет правильно, потому что лучше всего использовать хуки.

Зайдите в functions.php и добавьте туда следующую функцию:

function my_custom_ajax() {
  ?>

  <script type="text/javascript" >
    jQuery(document).ready(function($) {

        var data = {
            action: 'ACTION_NAME',
            first_name: 'Ivan',
            last_name: 'Ivanov',
            _ajax_nonce: '<?php echo wp_create_nonce( 'my_ajax_nonce' ); ?>'
        };

        // начиная с 2.8 ajaxurl всегда определяется в admin-ajax.php
        // Если вам нужно, чтобы это работало на внешней стороне сайта для гостей и обычных пользователей, тогда удалите комментарий ниже:
        // var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
        jQuery.post(ajaxurl, data, function(response) {
            alert('Ответ сервера: ' + response);
        });
    });
  </script>

  <?php
}
add_action('wp_footer', 'my_custom_ajax');

wp_footer добавить jQuery код перед </body> в вашей теме.

Далее под функцией  add_action('wp_footer', 'my_custom_ajax') нужно дописать следующее:

//если вы хотите принимать запрос только от авторизованных пользователей, тогда добавьте этот хук
add_action('wp_ajax_ACTION_NAME', 'my_AJAX_processing_function');

//если вы хотите получить запрос от неавторизованных пользователей, тогда добавьте этот хук
add_action('wp_ajax_nopriv_ACTION_NAME', 'my_AJAX_processing_function');

//Если хотите, чтобы оба вариант работали, тогда оставьте оба хука

Хуки выше должны иметь уникальные имена на подобии wp_ajax_ACTION_NAME и wp_ajax_nopriv_ACTION_NAME. Вы, в свою очередь, можете назвать их как угодно, но не забудьте дописать название action (в этом примере это ACTION_NAME ), которые вы отправляется через Ajax.

Вторым аргументом для add_action() пишется функция, которая будет обрабатывать Ajax запрос. Её пример приведен ниже.

function my_AJAX_processing_function(){
  check_ajax_referer('my_ajax_nonce');

  $first_name = $_POST['first_name'];
  $last_name = $_POST['last_name'];

  if( empty($first_name) || empty($last_name) ) {
    echo json_encode(['success' => 0, 'message' => 'Вы не указали имя или фамилию.']);
    wp_die();
  } 

  echo json_encode(['success' => 1, 'message' => 'Все окей.']);
  wp_die();
}

Ajax код приведенный в начале этой записи отправляет запрос с nonce, которые создается с помощью функции wp_create_nonce() (в целях безопасности).

Далее, на 3 строке (в коде выше), проверяется my_ajax_nonce, который был отправлен через Ajax и check_ajax_referer() вернет булевое значение, которое вы можете занести в if и вывести пользователю ошибку.

Если все окей, то мы получаем параметры имени и фамилии в  $first_name и $last_name и далее проверяем их на заполненность. Если они пустые, то выводим ошибку и на этом скрипт прерывается функцией wp_die(). Если все окей, то также выводим сообщение и прерываем скрипт.

Полный код

Полный код описанный в этой записи выглядит следующим образом:

function my_custom_ajax() {
  ?>

  <script type="text/javascript" >
    jQuery(document).ready(function($) {

        var data = {
            action: 'ACTION_NAME',
            first_name: 'Ivan',
            last_name: 'Ivanov',
            _ajax_nonce: '<?php echo wp_create_nonce( 'my_ajax_nonce' ); ?>'
        };

        // начиная с 2.8 ajaxurl всегда определяется в admin-ajax.php
        // Если вам нужно, чтобы это работало на внешней стороне сайта для гостей и обычных пользователей, тогда удалите комментарий ниже:
        // var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
        jQuery.post(ajaxurl, data, function(response) {
            alert('Ответ сервера: ' + response);
        });
    });
  </script>

  <?php
}
add_action('wp_footer', 'my_custom_ajax');

//если вы хотите принимать запрос только от авторизованных пользователей, тогда добавьте этот хук
add_action('wp_ajax_ACTION_NAME', 'my_AJAX_processing_function');

//если вы хотите получить запрос от неавторизованных пользователей, тогда добавьте этот хук
add_action('wp_ajax_nopriv_ACTION_NAME', 'my_AJAX_processing_function');

//Если хотите, чтобы оба вариант работали, тогда оставьте оба хука

function my_AJAX_processing_function(){
  check_ajax_referer('my_ajax_nonce');

  $first_name = $_POST['first_name'];
  $last_name = $_POST['last_name'];

  if( empty($first_name) || empty($last_name) ) {
    echo json_encode(['success' => 0, 'message' => 'Вы не указали имя или фамилию.']);
    wp_die();
  } 

  echo json_encode(['success' => 1, 'message' => 'Все окей.']);
  wp_die();
}

Использованные WordPress функции

Вывод

В WordPress работа с Ajax выглядит достаточно сложным процессом на самых первых порах. Как только вы повторите этот процесс 2-3 раза, вы сможете это делать с закрытыми глазами. Мне лично хватило всего 1 раза.