Краткий ответ: если не работает admin-ajax.php WordPress, сначала откройте DevTools → Network и посмотрите точный статус запроса: 400, 403, 404, 500, 502, 504, ответ “0”, пустой ответ или HTML вместо JSON. Чаще всего причина в неправильном action, отсутствии wp_ajax/wp_ajax_nopriv hook, ошибке nonce, блокировке WAF/security-плагином, кеше, PHP Fatal error, конфликте плагинов, WooCommerce, нехватке ресурсов хостинга или неправильном URL admin-ajax.php.
admin-ajax.php — это файл WordPress, через который многие плагины, темы, формы, фильтры, корзина WooCommerce, автосохранение, Heartbeat API и кастомные функции отправляют AJAX-запросы без перезагрузки страницы.
Если admin-ajax.php ломается, это может выглядеть как зависшая форма, неработающая кнопка, бесконечный спиннер, ошибка оформления заказа, неработающий фильтр товаров, проблемы в админке, медленная загрузка страницы или ошибка в консоли браузера.
admin-ajax.php сам по себе редко “ломается”. Обычно ломается конкретный AJAX-запрос, который идёт через этот файл. Поэтому важно смотреть не только URL, а ещё action, payload, HTTP-статус, response, headers и PHP-логи.
| Симптом | Возможная причина | Что проверить |
|---|---|---|
| Ответ 400 | нет action, неправильный action, пустой запрос | Network → Payload, PHP hook |
| Ответ 403 | WAF, security-плагин, nonce, IP-блокировка | логи безопасности, ModSecurity, nonce |
| Ответ 404 | файл недоступен, блокировка wp-admin, серверное правило | существует ли файл, .htaccess, Nginx |
| Ответ 500 | PHP Fatal error, конфликт плагина, тема | debug.log, error_log, последний обновлённый плагин |
| Ответ 502/504 | timeout, перегрузка PHP/MySQL, долгий обработчик | хостинг, slow log, Query Monitor |
| Ответ “0” | action не найден, нет wp_die, нет обработчика | wp_ajax_{action}, wp_ajax_nopriv_{action} |
| HTML вместо JSON | редирект, ошибка, кеш, warning, login page | Response, headers, debug.log |
| Долго грузится | тяжёлый AJAX, Heartbeat, WooCommerce fragments | Network Timing, Query Monitor, cron |
Если admin-ajax.php отдаёт 403, сначала проверьте материал WordPress показывает ошибку 403. Если проблема появилась после обновления, посмотрите статью после обновления плагина сломался сайт WordPress.
Диагностику нужно начинать в браузере, а не в PHP-файлах. Самое важное — увидеть конкретный AJAX-запрос и понять, что он отправляет и что получает в ответ.
В браузере нажмите F12, откройте вкладку Network и повторите действие, которое не работает: отправка формы, сохранение настроек, фильтр, добавление товара в корзину, клик по кнопке или оформление заказа.
В Network найдите запрос:
/wp-admin/admin-ajax.php
Проверьте:
Для admin-ajax.php параметр action обязателен. По нему WordPress понимает, какой PHP-обработчик вызвать.
Если в запросе нет action или он не совпадает с PHP hook, WordPress может вернуть 400, “0” или пустой ответ.
Пример логики:
action: 'sc_test_ajax'
В PHP должен быть обработчик:
add_action('wp_ajax_sc_test_ajax', 'sc_test_ajax_handler');
Для гостей дополнительно нужен:
add_action('wp_ajax_nopriv_sc_test_ajax', 'sc_test_ajax_handler');
Частая ошибка: AJAX работает для администратора, но не работает для обычного посетителя. Это значит, что есть обработчик только для авторизованных пользователей.
Nonce защищает AJAX-запрос от случайных и поддельных действий. Если nonce не передаётся, устарел или проверяется не тем ключом, обработчик может вернуть 403, ошибку безопасности или “0”.
Проверьте:
Если admin-ajax.php возвращает 500 или пустой ответ, почти всегда нужно смотреть логи.
Ищите:
Если запрос возвращает 403, 406 или HTML-страницу блокировки, вероятно, его режет firewall.
Проверьте:
Если форма отправки заявок работает через AJAX и перестала отправляться, дополнительно проверьте статью Не приходят заявки с сайта WordPress.
Если не хотите рисковать сайтом и тратить время на эксперименты, можно оставить заявку. Я посмотрю задачу и предложу аккуратное решение.
Исправление зависит от ответа admin-ajax.php. Нельзя одинаково исправлять 400, 403, 500 и долгий timeout. Ниже безопасный порядок действий.
Проверьте, что в запросе есть action и он совпадает с PHP hook.
403 означает запрет доступа. Причина может быть в nonce, security-плагине, WAF, IP-блокировке, cookies или правилах сервера.
Если 404 приходит именно на файл admin-ajax.php, это часто серверная проблема: файл недоступен, путь заблокирован, wp-admin закрыт правилом или сервер не отдаёт реальный файл.
500 почти всегда требует проверки PHP-логов. Сам браузер обычно не покажет причину.
Долгий admin-ajax.php часто связан не с ошибкой, а с тяжёлым обработчиком. Это может быть WooCommerce cart fragments, Heartbeat API, фильтры, поиск, отчёты, импорт, синхронизация, CRM, Telegram, внешнее API или медленный SQL-запрос.
Если проблема выглядит как постоянные тормоза админки, полезно проверить статью Медленно работает админка WordPress.
Важно: код ниже может повлиять на AJAX-запросы, формы, WooCommerce, корзину, оплату, личный кабинет и безопасность. Перед изменениями сделайте backup. Не отключайте nonce, capability checks и security-плагины на рабочем сайте без понимания причины.
Куда вставлять PHP: functions.php дочерней темы или отдельный мини-плагин.
add_action('wp_enqueue_scripts', 'sc_enqueue_ajax_script');
function sc_enqueue_ajax_script() {
wp_enqueue_script(
'sc-ajax-script',
get_stylesheet_directory_uri() . '/assets/js/sc-ajax.js',
array('jquery'),
'1.0.0',
true
);
wp_localize_script('sc-ajax-script', 'sc_ajax_data', array(
'nonce' => wp_create_nonce('sc_ajax_nonce'),
));
}
add_action('wp_ajax_sc_test_ajax', 'sc_test_ajax_handler');
add_action('wp_ajax_nopriv_sc_test_ajax', 'sc_test_ajax_handler');
function sc_test_ajax_handler() {
check_ajax_referer('sc_ajax_nonce', 'security');
wp_send_json_success(array(
'message' => 'AJAX работает',
));
}
Куда вставлять JS: файл дочерней темы /assets/js/sc-ajax.js.
jQuery(document).ready(function () {
jQuery(document).on('click', '.sc-test-ajax-button', function (event) {
event.preventDefault();
jQuery.ajax({
url: '<?php echo admin_url("admin-ajax.php") ?>',
type: 'POST',
dataType: 'json',
data: {
action: 'sc_test_ajax',
security: sc_ajax_data.nonce
},
success: function (response) {
console.log(response);
},
error: function (xhr) {
console.log(xhr.status);
console.log(xhr.responseText);
}
});
});
});
Откройте:
https://example.com/wp-admin/admin-ajax.php
Если файл доступен, часто будет ответ 0. Это не всегда ошибка. Это может означать, что файл открылся, но action не передан.
Куда выполнять: терминал или SSH.
curl -I https://example.com/wp-admin/admin-ajax.php
Проверить POST-запрос с action:
curl -X POST https://example.com/wp-admin/admin-ajax.php -d "action=sc_test_ajax"
Куда вставлять: wp-config.php, выше строки “That’s all, stop editing”.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
После теста проверьте:
/wp-content/debug.log
В JS можно временно вывести данные перед AJAX-запросом:
console.log({
action: 'sc_test_ajax',
security: sc_ajax_data.nonce
});
Куда выполнять: SSH в корне сайта.
grep -RIn "wp_ajax_" wp-content/themes wp-content/plugins
grep -RIn "admin-ajax.php" wp-content/themes wp-content/plugins
После правильного исправления admin-ajax.php должен отвечать ожидаемо: форма отправляется, фильтр работает, кнопка выполняет действие, WooCommerce не зависает, админка не тормозит, а Network показывает понятный HTTP-статус и нормальный response.
Хороший результат:
Heartbeat API тоже использует admin-ajax.php. Если запросы идут слишком часто, админка может тормозить. Не отключайте Heartbeat полностью без теста: он влияет на автосохранение и блокировку редактирования.
WooCommerce может использовать AJAX для обновления корзины. Если cart fragments создают нагрузку, нужно смотреть конкретный сайт, тему, кеш и поведение корзины. Глобальное отключение может сломать мини-корзину.
admin-ajax.php нельзя кешировать как обычную страницу. Если кеш или CDN отдаёт старый HTML/JSON, запросы могут вести себя неправильно.
Если сайт работает на HTTPS, а AJAX идёт на HTTP, браузер может блокировать запрос. Проверьте siteurl/home, SSL, редиректы и URL admin-ajax.php.
Если AJAX-запрос идёт с другого домена, браузер может заблокировать его из-за CORS. Для обычных WordPress-форм лучше отправлять запросы на тот же домен.
Если запрос содержит HTML, JSON, iframe, script, base64 или длинный текст, WAF может принять его за атаку. В таком случае нужно не отключать защиту полностью, а сделать точечное исключение.
На фронтенде переменная ajaxurl обычно не определена автоматически. Её нужно передавать через wp_localize_script или использовать корректный URL admin-ajax.php.
Если AJAX должен работать для гостей, одного wp_ajax_action недостаточно. Нужен wp_ajax_nopriv_action.
Без action WordPress не знает, какой обработчик вызвать. В результате можно получить 400 или “0”.
Для JSON-ответов лучше использовать wp_send_json_success() или wp_send_json_error(). Так WordPress корректно завершит AJAX-запрос.
Nonce — важная часть безопасности. Если проверка мешает, нужно исправить передачу nonce, а не удалять защиту.
Если страница долго кешируется, nonce может устареть. Это часто ломает формы, AJAX-кнопки и фронтенд-действия.
В Response часто уже написана причина: PHP warning, HTML ошибки, блокировка WAF, login page, 0, JSON error или fatal error.
Возможная причина: не передан action, action не совпадает с PHP hook, обработчик не подключён или не завершает ответ правильно.
Что делать: проверить Payload, wp_ajax_{action}, wp_ajax_nopriv_{action}, имя функции и wp_send_json/wp_die.
Возможная причина: пустой или некорректный action, неправильный формат запроса, ошибка в JS.
Что делать: проверить Network → Payload, console.log перед отправкой и соответствие action в PHP.
Возможная причина: nonce не прошёл проверку, WAF, security-плагин, Cloudflare, IP-блокировка или запрет wp-admin.
Что делать: проверить nonce, security logs, WAF events, .htaccess и правила защиты wp-admin.
Возможная причина: файл недоступен, wp-admin закрыт правилом, неправильный путь, серверная конфигурация.
Что делать: проверить наличие файла, .htaccess, Nginx config, права и исключение для admin-ajax.php.
Возможная причина: PHP Fatal error, конфликт плагина, ошибка темы, memory limit, несовместимость PHP.
Что делать: включить debug.log, проверить error_log, отключить проблемный плагин, проверить functions.php.
Возможная причина: тяжёлый SQL-запрос, внешний API, WooCommerce, Heartbeat, импорт, cron, медленный хостинг.
Что делать: проверить action, Query Monitor, slow query log, HTTP API calls и нагрузку сервера.
Возможная причина: нет wp_ajax_nopriv_{action}, nonce кешируется, действие требует авторизации.
Что делать: добавить nopriv hook, проверить capability checks и кеш страницы.
Возможная причина: JS не подключён, не передан nonce, другой post_id, конфликт шаблона или кеш.
Что делать: проверить source страницы, Network, Console, подключение скрипта и данные запроса.
Чаще всего из-за неправильного action, отсутствия wp_ajax/wp_ajax_nopriv hook, ошибки nonce, security-плагина, WAF, кеша, PHP Fatal error, конфликта плагинов или тяжёлого обработчика.
Откройте DevTools → Network, повторите действие и найдите запрос к /wp-admin/admin-ajax.php. Проверьте HTTP-статус, Payload, action, response и время выполнения.
Обычно не найден обработчик action, action не передан, нет нужного wp_ajax/wp_ajax_nopriv hook или PHP-функция не возвращает корректный ответ.
Обычно запрос блокирует nonce-проверка, security-плагин, WAF, ModSecurity, Cloudflare, IP-блокировка или правило доступа к wp-admin.
Это файл WordPress в папке wp-admin, через который обрабатываются AJAX-запросы плагинов, тем, админки, форм, WooCommerce и кастомного функционала.
Файл находится по пути /wp-admin/admin-ajax.php. На сайте он обычно доступен по адресу https://example.com/wp-admin/admin-ajax.php.
Причина обычно не в самом файле, а в конкретном AJAX action: тяжёлый SQL-запрос, внешний API, WooCommerce, Heartbeat, импорт, cron, медленный PHP или перегруженный хостинг.
Полностью отключать нельзя. Это может сломать формы, WooCommerce, админку, автосохранение, фильтры, корзину, личный кабинет и плагины.
Нужно найти конкретное правило или событие блокировки и сделать точечное исключение. Полностью отключать защиту без понимания причины не стоит.
Скорее всего, добавлен только hook wp_ajax_action. Для гостей нужен дополнительный hook wp_ajax_nopriv_action.
На фронтенде ajaxurl обычно не определён автоматически. Нужно передать URL через wp_localize_script или другим корректным способом.
Кеш может сохранить старый nonce, старые JS-файлы или неправильный ответ. Исключите AJAX-запросы и динамические страницы из агрессивного кеширования.
Посмотрите action в Network → Payload. Потом найдите этот action в коде плагинов через grep или отключайте подозрительные плагины на staging-копии.
Если admin-ajax.php ломает заявки, WooCommerce checkout, личный кабинет, формы, фильтры, оплату или админку, лучше не исправлять наугад. Нужна проверка Network, action, PHP-логов, WAF, кеша и обработчиков.
Если не работает admin-ajax.php WordPress, не нужно сразу отключать все плагины или править ядро WordPress. Сначала нужно открыть Network, найти конкретный запрос, посмотреть action, HTTP-статус, response, headers и время выполнения.
Основные причины — неправильный action, отсутствие wp_ajax_nopriv для гостей, ошибка nonce, WAF/security-блокировка, кеш, PHP Fatal error, конфликт плагинов, WooCommerce, Heartbeat API или медленный обработчик.
Самый безопасный порядок: backup, Network, Payload, debug.log, проверка hooks, nonce, security-плагинов, WAF, кеша и PHP-логов. Так можно исправить AJAX точечно и не сломать формы, заявки, корзину, оплату и админку.
Об авторе