JS向PHP发送JSON数据时后端接收为空的问题排查
问题根因
- 核心错误1:fetch请求的
body传值错误。FormData实例的内容存储在内部属性中,不存在data这个公开属性,你写body: data.data实际传入的是*undefined*,相当于没有发送任何请求体,这就是浏览器网络面板无提交数据、后端收不到内容的直接原因。 - 核心错误2:字段传值方式错误。你把序列化后的JSON字符串包装成
Blob对象再append到FormData中,这类文件/二进制类型字段PHP不会解析到$_POST数组里,只会存入$_FILES,就算你传对了FormData实例,也无法通过$_POST['data']拿到内容。 - 额外问题:fetch的响应对象如果要读取后端返回的文本内容,必须手动调用
resp.text()/resp.json()等解析方法,你原来的写法只能拿到响应头对象,看不到后端输出的实际结果。
正确实现方案
前端代码修正(保留FormData提交方式,适配原有PHP逻辑改动最小)
只需要修改testBud函数的提交逻辑即可,Excel解析部分不需要改动:
function testBud(dt1){ const jsonStr = JSON.stringify(dt1) const formData = new FormData(); // 直接把JSON字符串作为普通字段追加,不要包装成Blob formData.append("data", jsonStr); fetch("model/importBud.php", { method: "POST", body: formData, // 直接传入整个FormData实例,不要取自定义属性 // *禁止手动设置Content-Type请求头*,浏览器会自动补全multipart/form-data必需的boundary分隔符,手动设置会导致后端解析失败 }).then(resp => { if(!resp.ok) { const err = new Error("请求响应异常"); err.resp = resp; throw err; } return resp.text(); // 解析后端返回的文本内容 }).then(resText => { console.log("后端返回结果:", resText); }).catch(err => { console.error("请求失败:", err); }); }
可选简化方案:直接提交纯JSON请求体,不需要FormData
如果你不需要在请求里附带文件上传,直接传JSON格式请求体代码更简洁:function testBud(dt1){ fetch("model/importBud.php", { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(dt1) }).then(resp => { if(!resp.ok) throw new Error("请求响应异常"); return resp.text(); }).then(console.log).catch(console.error); }
后端PHP代码修正
如果使用上面的FormData提交方案,只需要补全字段存在性判断,避免未定义键报错即可:
<?php // 先判断字段是否存在且非空 if (isset($_POST['data']) && trim($_POST['data']) !== "") { // 把JSON字符串转成PHP数组,第二个参数传true代表返回关联数组,方便后续数据库操作 $dataArr = json_decode($_POST['data'], true); // 这里写你的数据校验、入库逻辑 echo "lleno,接收到数据条数:" . count($dataArr); }else{ echo "vacío,未接收到有效数据"; }
如果使用纯JSON提交的简化方案,PHP无法从
$_POST读取JSON请求体,需要读取原始请求流:<?php // 读取POST原始请求体 $rawJson = file_get_contents('php://input'); $dataArr = json_decode($rawJson, true); if (!empty($dataArr)) { // 数据校验、入库逻辑 echo "lleno,接收到数据条数:" . count($dataArr); }else{ echo "vacío,未接收到有效数据"; }
额外注意事项
- 你当前的Excel解析逻辑如果遇到多工作表的文件,
jsonObj只会保留最后一个工作表的内容,因为forEach循环会反复覆盖变量值,如果需要读取所有工作表内容,需要自行做数据合并或者按表名存储。 - 建议给
FileReader添加onerror监听,处理文件损坏、权限不足导致的读取失败问题,避免静默报错。
内容的提问来源于stack exchange,提问作者madison_sg
相关产品推荐
相关产品推荐

