向WordPress Admin Ajax提交嵌套JSON,为何无法访问对象数据?
WordPress AJAX无法获取嵌套JSON数据问题解决
问题场景
模拟WordPress Webhook集成时,无法在PHP函数中访问嵌套JSON payload的数据。预期接收的payload结构如下:
{ "data": { "attributes": { "user_name": "John Doe", "user_email": "johndoe@xyz.com" } } }
当前代码及错误现象
前端JavaScript代码
fetch(wp_ajax.ajax_url, { method: 'POST', body: new URLSearchParams({ action: 'course_signup', data: { attributes: { user_name: "John Doe", user_email: "johndoe@xyz.com" } } }) }) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.log(err));
后端PHP代码
<?php add_action('wp_ajax_course_signup', 'course_signup'); add_action('wp_ajax_nopriv_course_signup', 'course_signup'); function course_signup() { $data = json_decode($_POST['data']); $user_name = $data['attributes']['user_name']; $user_email = $data['attributes']['user_email']; $data = $_POST['data']; echo json_encode(array( "action" => $_POST["action"], "user_name" => $user_name, "user_email" => $user_email )); die(); }
错误现象
- 前端
console.log(response)返回结果:{ "action": "course_signup", "user_email": null, "user_name": null } - 浏览器Network标签中显示POST payload:
action: course_signup data: [object Object]
问题原因
URLSearchParams无法直接处理嵌套对象,会将对象自动转为字符串"[object Object]"。PHP端接收到的$_POST['data']是这个字符串,而非JSON数据,json_decode解析后得到null,导致后续取值全部为null。
解决方案
方案一:将嵌套对象转为JSON字符串发送
修改前端代码,把嵌套的data对象转为JSON字符串后再传入URLSearchParams;PHP端解析该字符串为关联数组(需给json_decode传入第二个参数true)。
修改后的前端代码
fetch(wp_ajax.ajax_url, { method: 'POST', body: new URLSearchParams({ action: 'course_signup', data: JSON.stringify({ attributes: { user_name: "John Doe", user_email: "johndoe@xyz.com" } }) }) }) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.log(err));
修改后的PHP代码
<?php add_action('wp_ajax_course_signup', 'course_signup'); add_action('wp_ajax_nopriv_course_signup', 'course_signup'); function course_signup() { // 解析JSON字符串为关联数组 $data = json_decode($_POST['data'], true); // 校验数据格式 if (!$data || !isset($data['attributes'])) { echo json_encode([ "action" => $_POST["action"], "error" => "无效的数据格式" ]); wp_die(); } $user_name = $data['attributes']['user_name']; $user_email = $data['attributes']['user_email']; echo json_encode([ "action" => $_POST["action"], "user_name" => $user_name, "user_email" => $user_email ]); wp_die(); }
方案二:直接发送JSON格式请求体
改用JSON格式发送请求体,设置Content-Type为application/json;PHP端从php://input读取原始请求体并解析。
修改后的前端代码
fetch(wp_ajax.ajax_url, { method: 'POST', headers: { 'Content-Type': 'application/json', // 若需WordPress权限验证,需添加nonce // 'X-WP-Nonce': wp_ajax.nonce }, body: JSON.stringify({ action: 'course_signup', data: { attributes: { user_name: "John Doe", user_email: "johndoe@xyz.com" } } }) }) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.log(err));
修改后的PHP代码
<?php add_action('wp_ajax_course_signup', 'course_signup'); add_action('wp_ajax_nopriv_course_signup', 'course_signup'); function course_signup() { // 读取原始JSON请求体 $raw_data = file_get_contents('php://input'); $request = json_decode($raw_data, true); // 校验数据格式 if (!$request || !isset($request['data']['attributes'])) { echo json_encode([ "action" => $request["action"] ?? '', "error" => "无效的数据格式" ]); wp_die(); } $user_name = $request['data']['attributes']['user_name']; $user_email = $request['data']['attributes']['user_email']; echo json_encode([ "action" => $request["action"], "user_name" => $user_name, "user_email" => $user_email ]); wp_die(); }
方案对比
- 方案一:兼容传统WordPress AJAX流程,改动小,适合简单嵌套数据。
- 方案二:符合RESTful API规范,支持更复杂的数据结构,需注意权限验证(如添加nonce)。
内容的提问来源于stack exchange,提问作者Joseph Farruggio
相关产品推荐
相关产品推荐

