使用Fetch API调用WordPress AJAX返回400错误的求助
WordPress Fetch API对接AJAX的正确方案
问题根源
你遇到的400错误和无法获取POST数据,核心是请求头与数据格式不匹配,以及WordPress AJAX的action参数解析规则导致的:
- 使用
FormData时手动设置Content-Type: application/json,会覆盖FormData自动生成的multipart/form-data头,导致WordPress无法解析请求体,返回400。 - 用
JSON.stringify发送数据时,PHP不会自动将JSON解析到$_POST数组,需要手动读取请求体;同时action参数如果只在JSON里,WordPress可能无法识别钩子。
方案一:使用FormData(推荐,兼容WordPress原生逻辑)
修正后的JS代码
let data = new FormData(); data.append('action', 'test_ajax_func'); data.append('test_string', 'SENDED DATA'); fetch(wp_localize_data.ajax_url, { method: 'POST', body: data, // 移除手动设置的Content-Type,FormData会自动生成正确的请求头 headers: { 'Cache-Control': 'no-cache', } }).then(response => { if(response.ok) { console.log('ajax_request: YEP'); response.json().then(data => console.log(data.result)); } else { console.log('ajax_request: NOPE'); } }).catch(error => console.log('ERROR: ' + error));
PHP代码(仅需添加安全判断,原逻辑保留)
add_action('wp_enqueue_scripts', 'theme_styles_and_scripts'); function theme_styles_and_scripts() { wp_register_script('ajax-test', get_template_directory_uri() . '/js/ajax-test.js', []); wp_localize_script('ajax-test', 'wp_localize_data', ['ajax_url' => admin_url('admin-ajax.php')]); wp_enqueue_script('ajax-test'); } add_action('wp_ajax_test_ajax_func', 'test_ajax_func'); add_action('wp_ajax_nopriv_test_ajax_func', 'test_ajax_func'); function test_ajax_func() { // 增加isset判断避免未定义索引报错 $test_string = isset($_POST['test_string']) ? $_POST['test_string'] : ''; $returned_string = 'RETURNS '. $test_string; echo json_encode(['result' => $returned_string]); die; }
方案二:使用JSON格式发送数据
如果偏好JSON格式,需要调整PHP端的读取逻辑:
JS代码
let data = { test_string: 'SENDED DATA' }; fetch(`${wp_localize_data.ajax_url}?action=test_ajax_func`, { method: 'POST', body: JSON.stringify(data), headers: { 'Content-Type': 'application/json', 'Cache-Control': 'no-cache', } }).then(response => { if(response.ok) { console.log('ajax_request: YEP'); response.json().then(data => console.log(data.result)); } else { console.log('ajax_request: NOPE'); } }).catch(error => console.log('ERROR: ' + error));
PHP代码(修改数据读取方式)
add_action('wp_enqueue_scripts', 'theme_styles_and_scripts'); function theme_styles_and_scripts() { wp_register_script('ajax-test', get_template_directory_uri() . '/js/ajax-test.js', []); wp_localize_script('ajax-test', 'wp_localize_data', ['ajax_url' => admin_url('admin-ajax.php')]); wp_enqueue_script('ajax-test'); } add_action('wp_ajax_test_ajax_func', 'test_ajax_func'); add_action('wp_ajax_nopriv_test_ajax_func', 'test_ajax_func'); function test_ajax_func() { // 读取JSON请求体并解析 $request_body = file_get_contents('php://input'); $data = json_decode($request_body, true); $test_string = isset($data['test_string']) ? $data['test_string'] : ''; $returned_string = 'RETURNS '. $test_string; echo json_encode(['result' => $returned_string]); die; }
关键说明
- WordPress AJAX的
action参数必须能被WordPress识别:要么放在FormData里(方案一),要么放在URL查询参数里(方案二),否则无法触发对应的钩子函数。 - 不要随意覆盖FormData的请求头,FormData会自动处理边界符等细节,手动设置
Content-Type会导致解析失败。 - 使用JSON格式时,PHP不会自动将数据填充到
$_POST,必须通过php://input读取并手动解析。
内容的提问来源于stack exchange,提问作者NamelessYoukai
相关产品推荐
相关产品推荐

