使用原生AJAX向PHP发送JSON时$_POST无法获取html参数
问题根因
报错由前后端两处逻辑不匹配共同导致,你之前用jQuery能正常运行,是因为jQuery默认发送application/x-www-form-urlencoded格式的表单请求,PHP可以自动解析参数到$_POST数组,换成原生XHR后逻辑不一致才出现问题:
- 前端传参错误:直接把原生JS对象传给
XMLHttpRequest.send()方法时,对象会被默认转成无意义的字符串[object Object],不会自动序列化为合法JSON结构,即使手动设置了Content-Type: application/json请求头也无效 - 后端接收逻辑错误:PHP的
$_POST超全局数组仅会自动解析application/x-www-form-urlencoded、multipart/form-data两种格式的请求体,当请求格式为application/json时,PHP不会自动解析JSON内容填充$_POST,直接读取$_POST['html']必然拿不到对应值。
修复方案
你可以任选以下一种方案修复,推荐第一种JSON传参的方案,逻辑更清晰。
方案1:保留JSON传参格式,前后端同步修正
前端修正
发送请求前必须用JSON.stringify()将JS对象序列化为合法JSON字符串,同时回调里注意解析后端返回的JSON结构,避免把整个JSON字符串直接渲染到页面:
<script> function preview() { var xhttp; xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { // 解析后端返回的JSON,取渲染后的内容插入页面 const res = JSON.parse(this.responseText); document.getElementById("output").innerHTML = res.output || ''; } }; var postData = { 'html' : document.getElementById("editor").value, }; xhttp.open("POST", "markuppreview.php"); xhttp.setRequestHeader('Content-type', 'application/json'); // 重点:序列化JSON字符串后再发送 xhttp.send(JSON.stringify(postData)); }; </script> <pre><textarea id="editor" name="content" placeholder="Enter your markup"></textarea></pre><br /> <button value="Preview" onclick="preview();">Preview</button> <h2>Preview</h2> <div id="output" style="height:100px"></div>
后端修正
不要从$_POST读取JSON请求参数,先读取原始请求输入流,再手动解析JSON:
$Parsedown = new Parsedown(); $Parsedown->setSafeMode(true); $data['success'] = false; $data['output'] = ''; // 读取原始请求体,解析JSON为关联数组 $rawInput = file_get_contents('php://input'); $requestData = json_decode($rawInput, true); // 校验字段存在后再做处理 if (isset($requestData['html'])) { $data['success'] = true; $data['output'] = $Parsedown->text($requestData['html']); } echo json_encode($data);
方案2:改回表单格式传参,后端无需修改
如果不需要传JSON格式,直接把请求改成和jQuery一致的表单编码格式即可,原有PHP代码不用调整:
- 删除前端代码里的
xhttp.setRequestHeader('Content-type', 'application/json');行 - 把postData改成URLSearchParams格式:
var postData = new URLSearchParams({ 'html': document.getElementById("editor").value });
- 直接调用
xhttp.send(postData)发送即可,PHP会自动把参数解析到$_POST数组。
内容的提问来源于stack exchange,提问作者MuppetDance
相关产品推荐
相关产品推荐

