在前后端数据交互中,假如后端使用 Go 返回 JSON:
json.NewEncoder(w).Encode(rsp)
不加任何头部设置时,前端这样写是可以解析的:
success: function(body) {
var resp = JSON.parse(body); // ✅ 可行
}
但当后端加上这句:
w.Header().Set("Content-Type", "application/json")
前端如果还这么写:
var resp = JSON.parse(body); // ❌ 报错:Unexpected token o in JSON at position 1
就会报错。
1. $.ajax 的 dataType 默认行为
如果你没有设置 dataType,jQuery 会根据==响应头(header)==自动判断数据类型。
如果返回头是 Content-Type: application/json,jQuery 会自动帮你解析成 JavaScript 对象。
因此:
// 后端加了 Content-Type: application/json 时
$.ajax({
url: "/api/xxx",
type: "POST",
success: function(body) {
console.log(typeof body); // 是 object 不是 string!
var resp = JSON.parse(body); // ❌ 你等于在 parse 一个对象,当然报错
}
});
这就是错误:“[object Object] is not valid JSON” 的来源。
2. 前端的 JSON.parse 是期望字符串类型
而你传给它的其实是一个已解析好的对象,再去 JSON.parse(object),就会报:
Uncaught SyntaxError: Unexpected token o in JSON at position 1
(因为对象的 toString() 是 “[object Object]”,不符合 JSON 格式)
✅ 正确做法
后端:
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(rsp)
前端 ✅ 不再手动解析
$.ajax({
url: "/api/xxx",
type: "POST",
dataType: "json", // 推荐显式设置
success: function(resp) {
console.log(resp.data); // 正确使用
}
});
// ❌ 不要在 success 回调中再 JSON.parse
success: function(resp) {
var obj = JSON.parse(resp); // 错的
}
当后端响应设置了 Content-Type: application/json,浏览器或 jQuery 会自动把响应体解析为 JSON 对象。此时,前端无需也不能再 JSON.parse(),否则会因为重复解析导致语法错误。
最好的做法是:
- 后端明确设置 Content-Type: application/json
- 前端通过 dataType: ‘json’ 自动接收对象
- 避免对返回结果再调用 JSON.parse
- 这样可以使前后端交互更健壮、更清晰。