chore(debug): 增加 ajax 调试工具定位 admin-ajax 400 "0" 来源
- assets/js/core/ajax-debug.js:ajaxSend 记录发往 admin-ajax 的 action 与参数,ajaxError/fetch 记录失败请求的 url/status/响应 - inc/aksrt-ajax-debug.php:admin_init 时记录每个 admin-ajax 请求的 action、是否有 wp_ajax_/wp_ajax_nopriv_ 处理器、POST 载荷至 wp-content/aksrt-ajax-debug.log(handled=0 即 400 "0" 的来源) - 开关:WP_DEBUG 或 URL 带 ?aksrt_ajax_debug=1(或常量 AKSRT_AJAX_DEBUG)
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* AJAX Debug — 记录 admin-ajax 收到的每个请求,用于定位未知 action(WP 返回 400 "0")。
|
||||
*
|
||||
* 启用条件:WP_DEBUG 开启,或请求带 ?aksrt_ajax_debug=1
|
||||
* 日志位置:wp-content/aksrt-ajax-debug.log
|
||||
*
|
||||
* 每行格式:
|
||||
* [时间] action=xxx handled=0/1(nopriv) login=0/1 post={...} referer=...
|
||||
* handled=0 表示 WP 没有任何 wp_ajax_{action} / wp_ajax_nopriv_{action} 处理器,
|
||||
* 这种请求 admin-ajax 会直接 die('0') 并返回 400 —— 即控制台看到的报错来源。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_ajax_debug_enabled')) :
|
||||
/**
|
||||
* Whether ajax debugging is on for this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function aksrt_ajax_debug_enabled(): bool {
|
||||
if (defined('AKSRT_AJAX_DEBUG') && AKSRT_AJAX_DEBUG) {
|
||||
return true;
|
||||
}
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
return true;
|
||||
}
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- 调试开关,无副作用。
|
||||
return isset($_GET['aksrt_ajax_debug']) && '1' === (string) wp_unslash($_GET['aksrt_ajax_debug']);
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_ajax_debug_log')) :
|
||||
/**
|
||||
* Append a line to the ajax debug log.
|
||||
*
|
||||
* @param string $line Log line.
|
||||
*/
|
||||
function aksrt_ajax_debug_log(string $line): void {
|
||||
$file = WP_CONTENT_DIR . '/aksrt-ajax-debug.log';
|
||||
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- 调试日志。
|
||||
@file_put_contents($file, '[' . current_time('Y-m-d H:i:s') . '] ' . $line . "\n", FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_ajax_debug_boot')) :
|
||||
/**
|
||||
* Hook the admin-ajax logger.
|
||||
*/
|
||||
function aksrt_ajax_debug_boot(): void {
|
||||
if (!aksrt_ajax_debug_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action('admin_init', static function (): void {
|
||||
if (!defined('DOING_AJAX') || !DOING_AJAX) {
|
||||
return;
|
||||
}
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- 只读记录,不修改状态。
|
||||
$action = isset($_REQUEST['action']) ? sanitize_key((string) wp_unslash($_REQUEST['action'])) : '';
|
||||
$has_logged = $action !== '' && has_action('wp_ajax_' . $action);
|
||||
$has_nopriv = $action !== '' && has_action('wp_ajax_nopriv_' . $action);
|
||||
$payload = $_POST;
|
||||
unset($payload['_wpnonce'], $payload['nonce'], $payload['_ajax_nonce']);
|
||||
aksrt_ajax_debug_log(sprintf(
|
||||
'action=%s handled=%d|%d login=%d post=%s referer=%s',
|
||||
$action !== '' ? $action : '(empty)',
|
||||
$has_logged ? 1 : 0,
|
||||
$has_nopriv ? 1 : 0,
|
||||
is_user_logged_in() ? 1 : 0,
|
||||
wp_json_encode($payload, JSON_UNESCAPED_UNICODE),
|
||||
isset($_SERVER['HTTP_REFERER']) ? (string) wp_unslash($_SERVER['HTTP_REFERER']) : ''
|
||||
));
|
||||
// phpcs:enable
|
||||
}, 1);
|
||||
}
|
||||
endif;
|
||||
|
||||
aksrt_ajax_debug_boot();
|
||||
Reference in New Issue
Block a user