yandex

Кодим HTML CSS JS PHP

Статьи о веб-разработке

Веб-разработка

AJAX в WordPress для начинающих

1668
0
Веб-разработка

Что такое 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 читает эти данные через $_POST
  • response.ok — проверяем HTTP-статус до парсинга JSON, fetch не выбрасывает ошибку при статусах 4xx/5xx
  • try/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 строится по простой схеме:

  1. JavaScript собирает данные в FormData и отправляет POST-запрос через fetch на admin-ajax.php с параметром action
  2. WordPress находит зарегистрированный хук wp_ajax_{action} и вызывает вашу PHP-функцию
  3. PHP-функция обрабатывает запрос и возвращает JSON через wp_send_json_success() или wp_send_json_error()
  4. JavaScript получает ответ, проверяет data.success и обновляет страницу

Придерживайтесь четырёх правил: всегда используйте nonce, не забывайте добавлять nopriv-хук для гостей, всегда завершайте PHP-функцию через wp_send_json_*, и проверяйте response.ok перед парсингом JSON. Этого достаточно, чтобы безопасно и правильно работать с AJAX в любом WordPress-проекте.

коментарии
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные