Вопрос или проблема
В моем плагине я использую два вызова Ajax на стороне сервера. Это работало хорошо. Но чтобы обеспечить ту же функциональность на стороне клиента, я загрузил копию этих двух функций с другими именами, и мой код выглядит так:
в главном файле моего плагина:
function my_action_callback(){
global $wpdb;
if (@$_POST['id']) {
$daty = $wpdb->get_results("select eemail_id,eemail_content,eemail_subject from " . WP_eemail_TABLE . " where 1=1 and eemail_status="YES" and eemail_id=" . $_POST['id']);
//echo "select eemail_id,eemail_content,eemail_subject from ".WP_eemail_TABLE." where 1=1 and eemail_status="YES" and eemail_id=".$_POST['id'];
if (!empty($daty)) {
foreach ($dat as $datt) {
echo $datt->eemail_content . "_" . $datt->eemail_subject;
die();
}
}
}
}
add_action('wp_ajax_nopriv_my_action', 'my_action_callback');
и в файле settings.js
function showEntryfront(id)
{
jQuery(document).ready(function($) {
var data = {
action: 'my_action',
id: id
};
jQuery.post(ajaxurl, data, function(response) {
//alert('Got this from the server: ' + response);
var n=response.split("_");
jQuery('textarea#mail_contents').text(n[0]);
$('#mail_subject').val(n[1]);
// jQuery('textbox#mail_subject').text(n[1]);
});
});
}
и страница плагина, которая вызывает showEntryfront(), выглядит следующим образом:
<select name="eemail_subject_drop" id="eemail_subject_drop" onchange="showEntryfront(this.value)">
<option value="">Select Email subject</option>
<?php echo $eemail_subject_drop_val; ?>
</select>
<input type="hidden" name="send" value="" id="send" /> </td>
<tr height="60px;"> <td>
<textarea name="mail_contents" id="mail_contents" rows="4" cols="40" ></textarea>
</td></tr>
Вторая функция делает то же самое. Различие только в таблице базы данных.
Тем не менее, моя консоль firebug показывает
ReferenceError: ajaxurl is not defined
jQuery.post(ajaxurl, data, function(response) {
и текстовое поле не заполняется данными из базы данных от таблицы WP_eemail_Table. Обратите внимание, что эта функциональность работала в панели управления wp-admin. Я знаю, что вызовы Ajax в админке загружаются автоматически через admin-ajax.php, но как я могу реализовать то же самое на стороне клиента? Есть ли ошибка в моем коде??
Вы должны локализовать скрипт, используя функцию wp_localize_script
. В админке ajaxurl
уже доступен. Но на стороне клиента нужно локализовать скрипт, чтобы определить ajaxurl
.
Пример:
wp_enqueue_script( 'custom-ajax-request', '/path/to/settings.js', array( 'jquery' ) );
wp_localize_script( 'custom-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
В WordPress core есть интегрированное решение для использования Ajax на стороне клиента!
В WordPress есть малоизвестная, но очень полезная библиотека JavaScript, доступная через объект JS window.wp
, вот так:
// В JS:
var action = 'my_action';
var data = {id: 123};
var promise = window.wp.ajax.post( action, data );
promise.always(function(response) {
console.log('Ajax done:', response);
});
// объект promise также имеет другие методы:
// `done()` / `fail()` / `progress()` / `state()` / `abort()`
Преимущество в том, что этот объект поддерживается и используется core WordPress. Можно быть уверенным, что он актуален, работает и является наиболее надежным способом обработки Ajax. Также обратите внимание, что вам не нужно обрабатывать код jQuery…
Если у вас нет объекта JavaScript window.wp
на стороне клиента, то вам нужно его загрузить, добавив этот скрипт core WP:
<?php
wp_enqueue_scripts( 'wp-util' );
Также убедитесь, что вы добавили wp-util
в зависимости ваших JS-скриптов, например:
wp_register_script( 'your-handle', 'https://your-domain.com/path/to/file.js', [ 'wp-util' ] );
.
Ответ или решение
Работа с AJAX-запросами на фронтенде WordPress может представлять собой определенные сложности, особенно если вы привыкли к стандартной реализации в админ-панели, где функционал AJAX поддерживается на уровне ядра без необходимости дополнительной настройки. Поэтому разберем, как правильно реализовать AJAX-запросы на пользовательской стороне сайта, и какие важные моменты необходимо учесть для их корректной работы.
Теория
Первое, что нужно учитывать при работе с AJAX в WordPress на фронтенде — различия в обработке URL запроса. В админ-панели URL для AJAX-запросов – admin-ajax.php
, который уже определен и готов к использованию через переменную ajaxurl
. На фронтенде такой переменной по умолчанию нет, поэтому необходимо осуществить ее передачу в JavaScript-код вручную с помощью функции wp_localize_script
.
Кроме того, важно понимать, что AJAX-запросы, выполняемые в контексте фронтенда, требуют определенного подхода к безопасности и валидации входных данных. Использование глобальной переменной $_POST
без проверки делает ваш сайт уязвимым для атак, включая SQL-инъекции. Вместо этого стоит использовать функции WordPress для безопасного взаимодействия с базой данных.
Пример
Рассмотрим шаги, которые нужно предпринять для корректной настройки AJAX на фронтенде вашего плагина:
Шаг 1: Регистрация и локализация скрипта
Прежде всего, необходимо зарегистрировать ваш JavaScript-файл и локализовать в нем ajaxurl
:
function my_enqueue_scripts() {
wp_enqueue_script( 'custom-ajax-request', plugin_dir_url( __FILE__ ) . 'path/to/settings.js', array( 'jquery' ), null, true );
wp_localize_script( 'custom-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );
Шаг 2: JavaScript-код для выполнения AJAX-запроса
Теперь, имея доступ к ajaxurl
через локализированную переменную в JavaScript, можно выполнить AJAX-запрос:
function showEntryfront(id) {
jQuery(document).ready(function($) {
var data = {
action: 'my_action',
id: id
};
jQuery.post(MyAjax.ajaxurl, data, function(response) {
var n = response.split("_");
jQuery('textarea#mail_contents').text(n[0]);
$('#mail_subject').val(n[1]);
});
});
}
Шаг 3: Создание PHP-функции для обработки AJAX-запроса
Необходимо зарегистрировать callback-функцию, которая будет обрабатывать AJAX-запрос на сервере:
function my_action_callback() {
global $wpdb;
if ( isset($_POST['id']) && is_numeric($_POST['id']) ) {
$id = intval($_POST['id']);
$results = $wpdb->get_results($wpdb->prepare(
"SELECT eemail_id, eemail_content, eemail_subject FROM " . WP_eemail_TABLE . " WHERE eemail_status = %s AND eemail_id = %d",
'YES',
$id
));
if (!empty($results)) {
foreach ($results as $result) {
echo esc_html($result->eemail_content) . "_" . esc_html($result->eemail_subject);
wp_die();
}
}
}
wp_die();
}
add_action('wp_ajax_nopriv_my_action', 'my_action_callback');
add_action('wp_ajax_my_action', 'my_action_callback');
Применение
С учётом указанных выше шагов, такая реализация позволит корректно обрабатывать AJAX-запросы на фронтенде без возникновения ошибки ReferenceError: ajaxurl is not defined
. Переменная ajaxurl
будет доступна вашим скриптам, что позволит к ним обращаться без ошибок.
Важно отметить, что для надежной работы, необходимо убедиться в безопасности ваших AJAX-запросов. Это включает в себя использование функций проверки и фильтрации входных данных, таких как intval
и другая экранизация для устранения угрозы SQL-инъекций. Всегда проверяйте и фильтруйте данные, поступающие от пользователя, прежде чем работать с ними в базе данных.
Кроме того, использование встроенных инструментов WordPress, таких как использование window.wp.ajax
для отправки запросов, может сделать ваш код более читаемым и совместимым с будущими изменениями в ядре CMS. Это поможет избежать дублирования кода и снизит зависимости от сторонних библиотек, таких как jQuery.
Таким образом, применяя данные принципы и примеры, вы сможете создать эффективную и безопасную систему обработки AJAX-запросов на фронтенде вашего сайта на WordPress.