404 на AJAX-запросах в WordPress и WooCommerce обычно выглядит обманчиво: страница сайта открывается, корзина работает частично, а в консоли браузера или в Network видно, что запрос к admin-ajax.php или к AJAX-эндпоинту WooCommerce возвращает 404. В таких случаях проблема редко находится в одном месте. Чаще это сочетание неверного URL, конфликта с кешем, правил сервера, отключённого wp_ajax_* хука или сломанной загрузки скриптов.
Ниже — рабочий порядок диагностики и исправления, без лишних предположений. Если у вас не просто 404, а ещё и пустой ответ или 500, часть шагов всё равно пригодится: они помогают быстро сузить источник ошибки.
Как понять, что именно ломается
Сначала нужно отличить обычный 404 страницы от 404 именно на AJAX-запросе. Это разные проблемы. В браузере откройте DevTools, вкладку Network, повторите действие, которое вызывает ошибку, и найдите запрос с типом fetch, xhr или admin-ajax.php.
Что смотреть в ответе
- URL запроса — должен вести на корректный домен и путь WordPress.
- Status code — 404 на уровне сервера или WordPress.
- Response — если там HTML страницы 404, запрос не дошёл до обработчика.
- Initiator — какой скрипт вызвал AJAX, это помогает найти источник в теме или плагине.
Для WooCommerce отдельно проверьте, не ломается ли именно фронтенд-логика корзины и оформления заказа. У WooCommerce часть запросов идёт через собственные AJAX-механизмы, и если они падают, пользователь видит неочевидные симптомы: не обновляется мини-корзина, не меняется доставка, не пересчитывается итог.
Типовые причины 404 на AJAX
На практике чаще всего встречаются такие сценарии:
- в коде указан неверный путь к
admin-ajax.phpили к REST/AJAX endpoint; - скрипт подключён, но локализация данных с
ajax_urlне передаётся; - кеширующий плагин или серверный кеш отдаёт старый HTML со старым URL;
- правила
.htaccessили конфигурация nginx мешают обработке запроса; - обработчик
wp_ajax_*/wp_ajax_nopriv_*не зарегистрирован; - запрос уходит на другой домен из-за смешанного протокола, поддомена или CDN;
- в теме или плагине сломан JavaScript, который формирует запрос.
Пошаговое решение
1. Проверьте, куда реально уходит запрос
Если в консоли у вас есть код, который использует admin_url('admin-ajax.php'), убедитесь, что URL формируется на стороне PHP и передаётся в JS. Это базовый и самый надёжный способ.
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'theme-ajax',
get_stylesheet_directory_uri() . '/assets/js/theme-ajax.js',
array('jquery'),
'1.0.0',
true
);
wp_localize_script('theme-ajax', 'themeAjax', array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('theme_ajax_nonce'),
));
});В JS используйте именно это значение, а не захардкоженный путь:
jQuery(function ($) {
$.post(themeAjax.ajaxUrl, {
action: 'theme_check_status',
nonce: themeAjax.nonce
})
.done(function (response) {
console.log(response);
})
.fail(function (xhr) {
console.log('AJAX failed', xhr.status, xhr.responseText);
});
});2. Убедитесь, что обработчик зарегистрирован
Если запрос доходит до admin-ajax.php, но сервер отвечает 404 или пустым результатом, проверьте наличие хука. Для авторизованных и неавторизованных пользователей нужны разные регистрации, если запрос доступен с фронтенда.
add_action('wp_ajax_theme_check_status', 'theme_check_status');
add_action('wp_ajax_nopriv_theme_check_status', 'theme_check_status');
function theme_check_status() {
check_ajax_referer('theme_ajax_nonce', 'nonce');
wp_send_json_success(array(
'message' => 'OK',
'time' => current_time('mysql'),
));
}Если забыть wp_ajax_nopriv_*, запросы от гостей не будут обработаны. Это частая причина, когда всё работает в админке, но ломается на публичной части сайта.
3. Очистите кеш и проверьте CDN
Если URL в коде правильный, а 404 появляется только у части пользователей, проверьте кеш. Статический HTML может содержать старый путь к скрипту или старую конфигурацию AJAX. Особенно это заметно после переноса сайта, смены домена, включения HTTPS или замены темы.
Что сделать:
- очистить кеш плагина;
- сбросить серверный кеш, если он есть;
- очистить CDN-кеш;
- пересохранить постоянные ссылки в Настройки → Постоянные ссылки;
- проверить, не кэшируется ли
admin-ajax.phpна уровне прокси.
4. Сравните поведение с отключёнными плагинами
Если 404 появляется только на конкретной странице или только в WooCommerce, временно отключите плагины, которые вмешиваются в кеширование, минификацию, оптимизацию JS или безопасность. Такие плагины иногда переписывают URL или ломают порядок загрузки скриптов.
Удобный способ проверки — открыть сайт в режиме без кеша, а затем поочерёдно отключать плагины оптимизации. Если ошибка исчезает после отключения одного из них, ищите настройку, которая объединяет или откладывает JS-файлы.
5. Проверьте серверные правила
На Apache и nginx проблема может быть не в WordPress, а в маршрутизации. Если запрос к /wp-admin/admin-ajax.php возвращает 404 на уровне сервера, проверьте, что файл существует и что правила не блокируют доступ к wp-admin. После миграции сайта иногда остаются старые rewrite-правила или ограничения по IP.
Если вы используете nginx, полезно отдельно посмотреть логи доступа и ошибок. Для Apache — error_log и access_log. Ищите точный путь запроса и статус ответа.
Если проблема в WooCommerce
Для WooCommerce 404 на AJAX часто проявляется в сценариях корзины и оформления заказа. Например, обновление мини-корзины может идти через wc-ajax, а не через обычный admin-ajax.php. Если тема или плагин подменяет скрипты WooCommerce, запрос может уйти на несуществующий адрес.
Проверьте, загружается ли стандартный фронтенд WooCommerce и не отключены ли его скрипты вручную. Иногда разработчики убирают часть ассетов ради ускорения, а потом получают неработающий пересчёт корзины.
| Подход | Когда подходит | Минус |
|---|---|---|
Исправить URL через wp_localize_script | Сломан путь к AJAX | Нужно править тему или плагин |
| Отключить кеш для AJAX | 404 появляется только у части пользователей | Может снизить эффективность кеша |
Перепроверить хук wp_ajax_* | Запрос доходит, но обработчик не найден | Нужно знать точное имя action |
Как проверить, что исправление сработало
После правок не ограничивайтесь визуальной проверкой страницы. Нужно подтвердить, что запрос действительно обрабатывается.
- Откройте DevTools → Network.
- Повторите действие, которое раньше вызывало 404.
- Проверьте, что статус запроса стал
200или ожидаемым JSON-ответом. - Убедитесь, что в ответе нет HTML-страницы ошибки.
- Если это WooCommerce, проверьте корзину, мини-корзину и оформление заказа в режиме гостя и в авторизованной сессии.
Дополнительно можно временно добавить логирование в обработчик, чтобы увидеть, вызывается ли он вообще:
function theme_check_status() {
error_log('theme_check_status called');
check_ajax_referer('theme_ajax_nonce', 'nonce');
wp_send_json_success(array('ok' => true));
}Если строка не появляется в логах, запрос не доходит до PHP-обработчика. Тогда проблема почти наверняка в URL, маршрутизации или кешировании.
Частые ошибки и как их исправить
- Используют относительный путь к
admin-ajax.php— после смены домена или поддомена запрос уходит не туда. Решение: передавать URL черезadmin_url(). - Забывают
wp_ajax_nopriv_*— гости получают 404 или пустой ответ. Решение: регистрировать оба хука, если запрос нужен на фронтенде. - Кешируют AJAX-ответы — часть пользователей видит старый HTML или старый endpoint. Решение: исключить AJAX из кеша.
- Отключают скрипты WooCommerce без проверки — ломается обновление корзины. Решение: сначала проверить, какой именно файл нужен странице.
- Не проверяют nonce — запрос может работать, но это уже дыра в безопасности. Решение: использовать
check_ajax_referer().
Безопасность и производительность
AJAX-обработчики часто пишут быстро и без защиты, а потом оставляют в продакшене. Минимум, который стоит держать всегда: nonce-проверка, валидация входных данных и явный JSON-ответ через wp_send_json_success() или wp_send_json_error().
Если запрос выполняется часто, не делайте в нём тяжёлые операции без необходимости. Для публичных страниц лучше не тянуть лишние данные из базы на каждый клик. Иногда правильнее пересмотреть логику и перевести часть действий на кешируемый endpoint или на обычную серверную обработку формы.
Для сайтов с активным WooCommerce полезно отдельно проверить, не создаёт ли оптимизатор JS задержку или поломку порядка загрузки. Если после включения объединения скриптов AJAX стал падать, это не «особенность WordPress», а конкретная настройка, которую нужно исключить для проблемных страниц.
Если вам нужно не только ловить такие ошибки, но и регулярно проверять сайт на сбои, в WPDetect удобно собирать сигналы по логам и состоянию ключевых компонентов. Для чистки дублей, мусора и лишних следов после правок иногда полезен и Clearfy Pro, но он не заменяет ручную диагностику AJAX-проблемы.
Главная идея простая: сначала выясните, где именно рвётся цепочка — URL, хук, кеш или сервер. Только после этого имеет смысл править код. Иначе можно «починить» один запрос и сломать соседний сценарий в WooCommerce.