AJAX В WORDPRESS
Цель этой статьи — показать, как использовать AJAX при создании тем и плагинов в WordPress.
Содержание
- AJAX в административной панели WordPress
- AJAX на фронтенде (в теме)
- Переменная
ajaxurl
- Запрос через
jQuery.ajax()
- Запрос через
fetch()
- Логическое подключение AJAX хуков
- Безопасность: использование Nonce и проверка прав
- Включение кэширования для AJAX-запросов
- Поиск ошибок и уведомлений
- Отладка (вывод ошибок на экран)
- Ошибка при возврате данных
- Плагины
AJAX В АДМИНИСТРАТИВНОЙ ПАНЕЛИ WORDPRESS
С тех пор, как AJAX был внедрён в административную панель WordPress, использование этой функции в плагинах стало очень удобным. Давайте рассмотрим небольшой пример. Все будет реализовано в одном файле (в файле плагина или в файле functions.php
вашей темы).
1. ДОБАВЛЕНИЕ JAVASCRIPT
Сначала добавим JavaScript код на административную страницу, который будет отправлять AJAX-запрос.
Переменная ajaxurl
глобально определена на всех страницах административной панели, и её следует использовать в JavaScript-коде в качестве адреса для обработчика AJAX-запросов. Обычно это файл /wp-admin/admin-ajax.php
. Эта переменная не определена в теме (шаблоне), поэтому для фронтенда вам нужно определить её самостоятельно (об этом ниже).
2. СОЗДАНИЕ PHP-ФУНКЦИИ
Теперь создадим PHP-функцию для обработки AJAX-запроса. Добавьте следующий код в functions.php
(или в плагин):
add_action( 'wp_ajax_my_action', 'my_action_callback' );
function my_action_callback() {
$whatever = intval( $_POST['whatever'] );
$whatever += 10;
echo $whatever;
// Завершение работы необходимо, чтобы в ответе не было ничего лишнего
wp_die();
}
Здесь мы связываем функцию my_action_callback
с действием wp_ajax_my_action
. Это выглядит так: wp_ajax_(action)
, где вместо (action)
подставляется значение my_action
.
Вот и всё.
Использование AJAX в административной панели WordPress
Пример выше отлично подходит для начала использования AJAX в административной панели WordPress.
3. AJAX НА ФРОНТЕНДЕ (В ТЕМЕ)
На фронтенде используется другой хук для обработки AJAX-запросов: wp_ajax_nopriv_(action)
. Этот хук срабатывает для неавторизованных пользователей.
add_action( 'wp_ajax_my_action', 'my_action_callback' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
Таким образом, для того чтобы создать обработчик запросов для всех пользователей (как авторизованных, так и нет), необходимо прикрепить PHP-функцию к двум хукам сразу.
ПЕРЕМЕННАЯ AJAXURL
По умолчанию переменная window.ajaxurl
не создаётся на фронтенде, как это сделано в административной панели. Поэтому нам нужно создать переменную, которая будет содержать URL для AJAX-запросов.
Назовём её window.myajax.url
— это удобнее для фронтенда, так как в объекте window.myajax
мы можем добавлять дополнительные глобальные данные, связанные с AJAX.
Вариант 1
Чтобы избежать проблем с идентификаторами скриптов, можно добавить необходимые данные в начало секции HEAD перед загрузкой скриптов, например, вот так:
add_action( 'wp_head', 'myajax_data', 8 );
function myajax_data() {
$data = [
'url' => admin_url( 'admin-ajax.php' ),
];
?>
Вариант 2
В этом варианте мы добавим наши данные AJAX перед загрузкой указанного скрипта, используя функцию wp_add_inline_script()
.
add_action( 'wp_enqueue_scripts', 'myajax_data', 9999 );
function myajax_data() {
$data = [
'url' => admin_url( 'admin-ajax.php' )
];
wp_add_inline_script(
'theme-scripts',
'window.myajax = ' . wp_json_encode( $data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ),
'before'
);
}
В результате мы получим в заголовке сайта перед скриптом theme-scripts
данные в формате:
ЗАПРОС ЧЕРЕЗ jQuery.ajax()
Первое, что нужно сделать, — убедиться, что библиотека jQuery подключена на сайте.
Пример AJAX-кода для фронтенда
add_action( 'wp_footer', 'my_action_javascript', 99 ); // для фронтенда
function my_action_javascript() {
?>
Этот код можно вставить в файл functions.php
темы. Он будет работать для любой темы, единственное, что нужно — изменить название основного скрипта темы, который загружается после jQuery.
ЗАПРОС ЧЕРЕЗ FETCH()
Если jQuery не используется в проекте, запрос можно выполнить с помощью функции fetch()
.
Внимание: fetch()
отправляет данные через body
, а не как параметры POST, что может привести к проблемам с распознаванием действия AJAX.
Пример 1:
Используйте URLSearchParams()
для отправки данных в body
и установите заголовок Content-Type
как application/x-www-form-urlencoded
:
const requestData = {
action : 'add_application',
info : 'some info'
}
const queryData = new URLSearchParams();
for ( const key in requestData ) {
queryData.set( key, requestData[key] )
}
fetch( myajax.url, {
method: "POST",
body: queryData,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
})
.then(response => response.text())
.then(response => {
console.log(response);
});
Пример 2:
Используйте FormData()
для передачи данных в body
:
const form = document.querySelector('form.my-form');
let formData = new FormData(form);
formData.set('action', 'add_application');
fetch( myajax.url, {
method: "POST",
body: formData,
})
.then(response => response.text())
.then(response => {
console.log(response);
});
ЛОГИЧЕСКОЕ ПОДКЛЮЧЕНИЕ AJAX ХУКОВ
Я не углублялся в объяснение того, как правильно подключать AJAX через хуки в коде. Тем не менее, вот простая рекомендация:
Подключайте функции обработки только тогда, когда это имеет смысл — во время AJAX-запроса. Это уменьшит вероятность возникновения ошибок.
Пример правильного подключения:
if (wp_doing_ajax()) {
add_action( 'wp_ajax_myaction', 'ajax_handler' );
add_action( 'wp_ajax_nopriv_myaction', 'ajax_handler' );
}
БЕЗОПАСНОСТЬ: ИСПОЛЬЗУЙТЕ NONCES И ПРОВЕРКУ ПРАВ
Необходимо проверять AJAX-запросы, особенно если они могут изменять данные.
1. Код Nonce
Nonce — это уникальная строка, используемая только один раз, чтобы убедиться, что запрос пришёл из правильного источника. В WordPress есть функции wp_create_nonce()
и check_ajax_referer()
, позволяющие работать с nonce.
Создайте код nonce:
add_action( 'wp_enqueue_scripts', 'myajax_data', 99 );
function myajax_data() {
wp_localize_script( 'theme-script', 'myajax', [
'url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('myajax-nonce')
]);
}
При обработке запроса проверьте nonce:
add_action( 'wp_ajax_myajax-submit', 'myajax_submit' );
function myajax_submit() {
check_ajax_referer('myajax-nonce', 'nonce_code');
echo 'Возвращённые данные';
wp_die();
}
2. Проверка прав доступа
Необходимо проверять, имеет ли текущий пользователь достаточно прав для выполнения запроса.
if (!current_user_can('publish_posts')) {
die('Этот запрос доступен пользователям с правами автора и выше.');
}
ВКЛЮЧЕНИЕ КЭШИРОВАНИЯ ДЛЯ AJAX ЗАПРОСОВ
По умолчанию все AJAX-запросы не кэшируются браузером. В некоторых случаях кэширование может сократить использование ресурсов и увеличить скорость скрипта. Например, если у вас есть сложный фильтр продуктов, можно кэшировать результаты.
Чтобы включить кэширование для определённых AJAX-запросов, посмотрите на функцию nocache_headers()
.
ПОИСК ОШИБОК И УВЕДОМЛЕНИЙ
При выполнении AJAX-запросов могут возникать ошибки и нежелательные уведомления. Что касается отладки, вы можете использовать функции print_r()
или var_dump()
для проверки содержимого нужных переменных.
ОТЛАДКА (ВЫВОД ОШИБОК НА ЭКРАН)
WordPress не отображает ошибки запросов AJAX даже при включённом режиме отладки WP_DEBUG
. Чтобы включить отображение ошибок, добавьте следующий код:
if (WP_DEBUG && WP_DEBUG_DISPLAY && (defined('DOING_AJAX') && DOING_AJAX)) {
@ ini_set( 'display_errors', 1 );
}
ОШИБКА ПРИ ВОЗВРАТЕ ДАННЫХ
Если AJAX-запрос к файлу wp-admin/admin-ajax.php
не удался, то он вернёт ответ -1 или 0:
-1
— ошибка в проверке запроса.0
— возвращается пустой результат.
ПЛАГИНЫ
Плагин AJAX Simply — добавляет класс, который позволяет удобно и быстро писать AJAX-запросы на клиентской стороне и обрабатывать ответы на серверной стороне.
Эта статья является полезным ресурсом для начинающих разработчиков WordPress, желающих внедрить AJAX в свои проекты.