ajaxurl не определен во фронтенде
Я пытаюсь создать ajax-форму на фронтенде. Я использую следующий код
jQuery.ajax(
{
type: "post",
dataType: "json",
url: ajaxurl,
data: formData,
success: function(msg){
console.log(msg);
}
});
для которого я получаю ошибку
Uncaught ReferenceError: ajaxurl is not defined worklorAjaxBookForm @
?page_id=2:291onclick @ ?page_id=2:202
В то время как аналогичный код работает в административной панели. Какой URL я должен использовать для обработки ajax-запроса?

В бэкенде WordPress автоматически определяет глобальную переменную ajaxurl
.
Однако эта переменная не создаётся WordPress во фронтенде. Это означает, что если вы хотите использовать AJAX-запросы во фронтенде, вам необходимо самостоятельно определить такую переменную.
Хороший способ сделать это — использовать функцию wp_localize_script
.
Предположим, ваши AJAX-запросы находятся в файле my-ajax-script.js
. В таком случае добавьте wp_localize_script
для этого JS-файла следующим образом:
function my_enqueue() {
wp_enqueue_script( 'ajax-script', get_template_directory_uri() . '/js/my-ajax-script.js', array('jquery') );
wp_localize_script( 'ajax-script', 'my_ajax_object',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue' );
После локализации вашего JS-файла вы можете использовать объект my_ajax_object
в своём JS-файле:
jQuery.ajax(
{
type: "post",
dataType: "json",
url: my_ajax_object.ajax_url,
data: formData,
success: function(msg){
console.log(msg);
}
});

Можно ли использовать wp_localize_script
без необходимости использовать wp_enqueue_scritp
?

Вы используете handle скрипта в wp_localize_script, поэтому вам придется использовать wp_enqueue_script хотя бы для одного из ваших скриптов. Но... Не использовать wp_enqueue_script — не лучшая идея (вы рискуете получить конфликты и проблемы с зависимостями).

У меня нет внешних скриптов для загрузки, я просто хочу использовать ajaxurl для выполнения AJAX-запроса. Разве это невозможно?

И куда ты поместишь этот AJAX-вызов? Встроенным скриптом? Это очень плохая идея...

У меня отдельная форма, в которой я управляю валидацией, и при отправке делаю AJAX-запрос для отправки формы, конечно же, правильным способом через WordPress, добавляя хук. В любом случае, я нашел способ использовать ajaxurl.

Отлично... Я использую это в своем JavaScript на фронтенде, и работает просто замечательно :)

Я не понимаю. Что если вызовы делаются из нескольких отдельных файлов? Как тогда поступать? Нельзя ли просто "объявить" единый ajax URL для всего экземпляра WP? И почему это не делается автоматически?

для прямого использования ajaxurl добавьте в файл вашего плагина следующий код:
add_action('wp_head', 'myplugin_ajaxurl');
function myplugin_ajaxurl() {
echo '<script type="text/javascript">
var ajaxurl = "' . admin_url('admin-ajax.php') . '";
</script>';
}
после этого вы можете использовать переменную ajaxurl
для AJAX-запросов.

Этот ответ делает ajaxurl
практически таким же, как при использовании по умолчанию. Что намного лучше принятого ответа.

@Jules ajaxurl
остается доступным в *.js
файле. Для этого вам может потребоваться объявить переменную ajaxurl
на раннем этапе загрузки страницы. Еще один момент, который стоит учитывать - это вызов вашего внешнего *.js
файла. Внешний файл должен вызываться ПОСЛЕ того, как ajaxurl
был инициализирован и получил правильное значение URL.

А как насчёт конфликтов с другими плагинами или темами, которые объявляют переменную таким же образом? Я считаю, что вам стоит хотя бы добавить пространство имён для переменной. В любом случае, думаю, что принятый ответ имеет меньше шансов вызвать проблемы/конфликты в будущем. Но если вы точно знаете, что делаете, такой подход допустим.

В 2021 году подход немного изменился ;-)
function my_enqueue() {
// Подключаем скрипт с зависимостью от jQuery
wp_enqueue_script( 'ajax-script', get_template_directory_uri() . '/js/my-ajax-script.js', array('jquery') );
// Добавляем инлайн-скрипт с переменными перед основным скриптом
wp_add_inline_script( 'ajax-script',
'const myVariables = ' . json_encode(
array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
) ),
'before' );
}
// Регистрируем хук для подключения скриптов
add_action( 'wp_enqueue_scripts', 'my_enqueue' );
Источник: https://developer.wordpress.org/reference/functions/wp_add_inline_script/#comment-4632

Я сегодня наткнулся на это же решение, и если вам интересно, в документации по wp_localize_script()
есть дополнительная информация о том, когда использовать wp_add_inline_script()
вместо wp_localize_script()
.

Я использовал приведенный ниже код на сайте WordPress.
Мы можем использовать этот код для настройки ajaxurl следующим образом.
<?php echo esc_url(admin_url('admin-ajax.php')); ?>
Я также добавил пример AJAX, где можно использовать приведенную выше строку.
function setNotificationRead() {
fetch('<?php echo esc_url(admin_url('admin-ajax.php')); ?>', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
},
body: `action=yourFunctionsAction`,
credentials: 'same-origin'
}).then(response => {
return response.json();
}).then(data => {
if (data.status === 'true') {
console.log('Сделать что-то...');
}
});
}

После многих часов проб и ошибок мне удалось заставить это работать. Поэтому я делюсь тем, как реализовать ajax в WordPress с примером (начал с https://www.tweaking4all.com/web-development/wordpress/wordpress-ajax-example/#comment-562814 и адаптировал пример)
--используйте инструменты разработчика Chrome и отключите кеширование во вкладке Network --проверяйте консоль на наличие ошибок, первая цель - увидеть в консоли "ready!" при клике на кнопку, а если все работает, вы получите также красивый вывод!
--добавьте на сайт WordPress как пользовательский HTML-блок:
<div id="receiving_div_id">
<p>Пока ничего не загружено</p>
</div>
<button id="button_to_load_data">Получить Ajax-контент</button>
--добавьте в theme/js/button.js (создайте папку js):
jQuery("#button_to_load_data").click(function() {
console.log( "ready!" );
var data = {
'action' : 't4a_ajax_call', // название вашей PHP-функции!
'function' : 'show_files', // случайное значение, которое мы хотим передать
'fileid' : '7' // еще одно случайное значение для передачи
};
jQuery.post(my_ajax_object.ajax_url, data, function(response) {
jQuery("#receiving_div_id").html(response);
});
});
--добавьте в functions.php темы:
/* кастомный скрипт в functions.php темы */
/* подключение button.js (->my-script) и локализация admin-ajax.php для my-script */
function add_my_script() {
wp_enqueue_script( 'my-script',
get_template_directory_uri() . '/js/button.js',
array ( 'jquery' ),
false,
true
);
wp_localize_script( 'my-script', 'my_ajax_object',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
add_action( 'wp_enqueue_scripts', 'add_my_script' );
