服务器接受 JSON 数据格式不正确,绝大多数时候不是解析代码的问题,而是请求头里的 Content-Type、原始字符串本身或字符编码这三处没对齐。 先别急着改后端逻辑,按顺序查这三样,能省下大量排查时间。
json怎么接收数据格式不正确?先检查这三处
有一次我在处理一个接口时,前端明明传了 JSON,后端拿到的却是普通的文本字符串,所有字段都读不出来,后来发现,请求头里的 Content-Type 是 application/x-www-form-urlencoded,服务器端根本没有进入 JSON 解析流程,这是最常见的“格式不正确”假象。
症状:接口报错或字段都是 null
- 后端接口返回 400 Bad Request,提示消息体不可读。
- 字段值全部为
null,但是日志里能看到原始参数键值对。 - 解析时报
JSONParseException或Unexpected token。
如果你遇到这些,先从客户端发出的请求头查起。
关键点:Content-Type 必须写对
主流服务端框架(Spring Boot、Express、Flask)在解析请求体时,会先看 Content-Type,只有为 application/json(或者 application/json;charset=UTF-8)时,框架才会把请求体当作 JSON 处理,以下是实际踩坑对比:
| 发送方式 | Content-Type | 后端拿到的数据 |
|---|---|---|
| 表单提交 | application/x-www-form-urlencoded | 普通字符串 |
| 文件上传 | multipart/form-data | 表单字段 |
| fetch/axios 未设置 | text/plain;charset=UTF-8 | 原始字符串 |
| 正确 JSON 请求 | application/json | 可解析的 JSON 结构 |
修复方法很简单,在发送时显式设置请求头:
fetch('/api/user/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ userName: 'admin', password: '123456' })
})
实操:先用 curl 验证接口本身是否正常
用一条 curl 命令就能绕过前端,直接判断服务器能否正确接收 JSON:
curl -X POST http://localhost:8080/api/user/login
-H "Content-Type: application/json"
-d '{"userName":"admin","password":"123456"}'
如果这条命令能正常返回数据,说明接口本身没问题,问题就出在前端发送环节,如果这条命令也报格式错误,再继续往原始字符串方向排查。
服务器json数据格式错误排查:字符串与对象是两码事
不少新手会混淆“JSON 字符串”和“JSON 对象”,服务器接收到的其实是一段很长的字符串,需要经过解析才能变成可操作的对象,如果你把字符串直接当作对象处理,自然就会出现“格式不正确”的错觉。
常见场景:用错了解析函数
- 在 Node 中,把字符串交给
JSON.parse()后得到对象。 - 在 Python 中,用
json.loads(string)得到字典。 - 在 Java 中,用
ObjectMapper.readValue(jsonStr, User.class)。
如果不小心对已解析的对象再执行一次 JSON.parse,或者对字符串直接读取属性,都会抛出异常。
判断收到的数据是字符串还是对象
先打印原始请求体,看打印结果是否带引号。
注意,对象打印出来时键名是否带引号取决于语言环境和序列化方式,最可靠的办法是看变量的类型,前端发送时,一定要用 JSON.stringify() 包装数据,保证传输的是标准 JSON 字符串,后端接收后,再做一次解析。
常见的解析异常及含义
| 异常信息 | 含义 |
|---|---|
| Unexpected token ‘o’ in JSON | 把一个已解析的对象当字符串再次解析 |
| Unexpected token ‘ in JSON | 出现了单引号,JSON 只允许双引号 |
| Expecting property name enclosed in double quotes | 键名没有用双引号包裹 |
| Bad escaped character in JSON | 存在非法转义字符 |
json接收数据格式不对怎么办?按这套步骤走一遍
面对服务器提示 JSON 格式有问题,别盲改,这组排查顺序可以覆盖相当一部分情况。
第一步:打印原始请求体
在后端接口入口处,先不解析,直接打印请求体原始内容,这一步能区分是“没送到”还是“格式错”。
第二步:用校验工具检查字符串
把原始字符串拷贝到 JSON 校验工具里看是否合法,现在不少在线工具可以免费校验,对比几个常见的免费在线校验工具,功能差别不大,主要看能否一次性展示错误位置,挑选一个支持树形展示的即可。
第三步:检查数组和对象嵌套
大括号和中括号是否匹配?数组中每个元素用逗号隔开,最后一个元素后不能有逗号,经常有人把最后一个字段后面多写一个逗号,导致整个 JSON 失效。
{"name":"张三","age":20}
合法,下面这个就不合法:
{"name":"张三","age":20,}
因为 20 后面多了一个逗号。
第四步:检查键名和字符串值的引号
JSON 标准要求使用双引号,不能用单引号,键名也必须加双引号。{'name':'张三'} 在严格模式下会解析失败,应当写成 {"name":"张三"}。
第五步:替换特殊字符
字符串值中如果包含换行、回车、Tab 或反斜杠,直接写原文会导致解析失败,正确做法是使用转义符:
- 换行写成
n - 回车写成
r - Tab 写成
t - 双引号写成
" - 反斜杠写成
\
前后端json数据对接问题:编码和转义是隐形杀手
很多接口在本地测试一切正常,部署到服务器后却出现中文乱码或解析报错,这往往不是格式问题,而是编码问题。
统一编码是解决乱码的前提
行业共识认为,前后端统一使用 UTF-8 编码,能避免绝大多数跨平台中文乱码问题,服务器在返回响应时,不要只写 Content-Type: application/json,最好带上 charset=utf-8:
Content-Type: application/json; charset=utf-8
如果你的服务器用了默认的 ISO-8859-1 或 GBK,中文就会变成一串问号或乱码,特别是服务器所在地和本地环境不一致时,比如服务器部署在海外而本地是中文系统,这种差异更容易暴露出来。
BOM 头也可能让解析器报错
有些编辑器保存文件时会加入 BOM(字节顺序标记),这会在 JSON 字符串的开头增加不可见字符,服务器解析时可能报“意外的字符”,排查方法:用十六进制编辑器查看请求体的开头,如果有 EF BB BF 三个字节,去掉 BOM 再发送,保存文件时选择不带 BOM 的编码,或者在后端过滤掉开头多余字符。
转义不彻底导致的二次错误
前端发送的数据里如果包含反斜杠,比如路径 C:Usersname,必须写成 C:\Users\name,如果直接写单反斜杠,后端的 JSON 解析器会把它当作转义符,然后报错。
json格式校验失败原因及后端防御性写法
与其每次出了问题到处排查,不如在后端做防御性处理,至少要让错误信息足够清晰,而不是抛出一堆堆栈。
后端兜底:解析失败时返回 400
在 Java 的 Spring Boot 中,可以统一处理 HttpMessageNotReadableException:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<String> handleUnreadable(HttpMessageNotReadableException e) {
return ResponseEntity.badRequest().body("请求体格式不正确,请检查 JSON 语法");
}
}
在 Express 中,可以增加一个简单的中间件:
app.use((err, req, res, next) => {
if (err.type === 'entity.parse.failed') {
return res.status(400).send('JSON 解析失败');
}
next(err);
});
前端发送前自校验
前端在 JSON.stringify 遇到非法值时,会丢弃函数和 undefined,如果你把一个包含 undefined 的对象直接传给服务器,服务器会看到属性缺失,这种“格式不正确”其实来自序列化时丢失了数据,建议发送前封装一个安全的序列化方法,对特殊类型做转换。
日志里不要打印完整对象,只打印必要字段
打印完整请求体会让敏感信息泄露,还会让日志文件迅速膨胀,业内专家指出,排查阶段可以临时打印,但上线前一定要移除或改为只记录字段名和长度。
服务器json怎么接收数据格式不正确?常见问题解答
为什么服务器总是收到字符串而不是 JSON 对象?
因为 HTTP 传输本质上就是纯文本,服务器框架必须根据 Content-Type 决定是否调用 JSON 解析器。Content-Type 不是 application/json,或者请求体本身结构不合法,服务器就拿不到对象。
请求体里的换行符都需要转义吗?
是的,JSON 字符串内部不能出现真实换行符,必须用 n 转义,如果整个 JSON 字符串包含多行,那是允许的,但字符串值内的换行必须转义,否则解析器会认为字符串结束,从而报错。
Content-Type 不一致一定会报错吗?
多数情况下会,部分框架会尝试自动解析,但自动解析仅在请求体内容非常标准时才成功,为了避免不确定行为,无论前后端环境如何,显式声明 application/json 是规范做法。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/762114.html





