为何PostForm将JSON数据解析为Map键?如何实现正确解析?
问题描述
前端通过以下AJAX请求调用Go后端接口:
var ajaxParams = { type: 'POST', url: '/golang_endpoint', dataType: 'json', processData: false, timeout: timeout, contentType: 'application/json', data: JSON.stringify({"test": 1, "test2": "val"}), }; $.ajax(ajaxParams);
后端使用ParseForm解析请求后,req.PostForm结果异常:
req.ParseForm() fmt.Println(req.PostForm)
输出结果为:map[{"test":1,"test2":"val"}:[]]
请问为何ParseForm会出现这样的解析结果?如何才能将其解析为map[test: [1] test2: [val]]?
解析异常原因
ParseForm是Go专门用来解析**application/x-www-form-urlencoded**类型表单数据的方法,它会按照键值对的格式解析请求体。
而你的前端请求设置了contentType: 'application/json',同时用JSON.stringify把数据转成JSON字符串,还设置processData: false阻止jQuery自动处理数据格式。此时请求体是完整的JSON字符串,ParseForm无法识别JSON格式,会把整个JSON字符串当作表单的一个键,对应的值为空数组,所以才会得到map[{"test":1,"test2":"val"}:[]]这种结果。
解决方法
方法一:后端直接解析JSON数据(推荐,适配复杂数据结构)
如果原本就打算用JSON格式传递数据,无需使用ParseForm,直接读取请求体并解析JSON即可:
data, err := ioutil.ReadAll(req.Body) if err != nil { // 处理读取错误 } defer req.Body.Close() var m map[string]interface{} err = json.Unmarshal(data, &m) if err != nil { // 处理解析错误 } fmt.Println(m)
前端保持原AJAX配置不变:
var ajaxParams = { contentType: 'application/json', data: JSON.stringify({"test": 1, "test2": "val"}), // 其他参数保持不变 }; $.ajax(ajaxParams);
方法二:修改前端请求格式,适配ParseForm解析
如果一定要得到map[test: [1] test2: [val]]这种PostForm格式的结果,需要让前端发送application/x-www-form-urlencoded类型的表单数据:
var ajaxParams = { type: 'POST', url: '/golang_endpoint', dataType: 'json', // 去掉processData: false,默认值为true,jQuery会自动把对象转成表单格式 timeout: timeout, // 可省略contentType,默认就是application/x-www-form-urlencoded data: {"test": 1, "test2": "val"}, // 直接传对象,不要用JSON.stringify }; $.ajax(ajaxParams);
后端保持原ParseForm代码即可:
req.ParseForm() fmt.Println(req.PostForm) // 输出 map[test:[1] test2:[val]]
内容的提问来源于stack exchange,提问作者Peabrain
相关产品推荐
相关产品推荐

