目录
axios中常规请求
如果手工全局指定Content-Type为application/x-ww-form-urlencoder,如下:
//post请求的Content-Type
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
那么在发送请求的时候。大多数情况下,我们传的入参都是一个js对象,此时需要进行QS.stringify序列化操作,如下:
export function post(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, QS.stringify(params))
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err.data)
})
});
}
问题1
- QS.stringify做了什么操作?我能不能使用JSON.stringify来转换呢?
答案是不可以,两者转换后的结果有明显的不同,如下:
{"uid":"cs11","pwd":"000000als","username":"cs11","password":"000000als"} uid=cs11&pwd=000000als&username=cs11&password=000000als
上面是JSON.stringify的结果,下面是QS.stringify的结果。
问题2
- 为什么一定要QS.stringify序列话?我使用Jquery的ajax的时候,就直接在data区域写入参对象就行啊
其实也不一定非要QS.stringify序列化,如果入参的格式不是js对象,而是就像我们写好的 uid=cs11&pwd=123这样的字符串拼接格式,那么就不用再序列化操作。
主要缘故在于:
axios内部会自动对Object的入参进行转换,转换成json字符串,其实就是JSON.stringify的操作,同时,会指定Content-type为applicaltion/json。
transformRequest: [function transformRequest(data, headers) {
// ...
if (utils.isObject(data)) {
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
return JSON.stringify(data);
}
return data;
}]
后台是按照application/x-ww-form-urlencoder方式在接口中进行数据获取和处理的,这样的话,后台处理就会出问题。
同样的,如果后台的接口就是处理Content-Type=application/json类型的入参,那么根本就不用再使用QS序列化了,直接正常post即可,如果强制使用了,后台接口在处理的时候会获取失败。
关于后台
关于JFinal框架,3.5版本之前是不支持Content-Type=application/json的入参传参的,无法通过getPara获取参数信息,3.5版本之后有专门的getRawData的方法可以获取,具体可以查看文档。
对于SpringBoot框架,相对就简单了,为入参添加@RequestBody注解即可,如下:
@RequestMapping(value = "/index2", method = {RequestMethod.GET,RequestMethod.POST})
public String index2(@RequestBody Map<String,Object> p) {
System.out.println(p.toString());
return "success";
}
综上
前后台在对接的时候,一定要约定好入参格式,如果约定为纯JSON格式入参,即Content-Type=application/json。那么后台就要使用@RequestBody注解,接收的入参可以是一个固定格式的bean,也可以是一个Map。同时前台直接使用axios.post即可,不再需要使用QS序列化。
如果还是传统的入参方式,即Content-Type=application/x-ww-form-urlencoder,后台处理相对简单,JFinal直接通过getPara获取一个个参数,SpringBoot可以直接通过req.getParameter获取参数。前端axios在使用的时候,要对data进行QS序列化操作,不然总会有意想不到的错误。这种情况下,其实也可以传JSON格式的入参,只不过,还指定一下入参名,入参内容就是一串JSON格式,同时对JSON格式的入参提前进行JSON.stringify,然后放到对象中,再进行QS。例如:
var obj = {"un":"zs","pw":"123455"}
var data = {"params" : JSON.stringify(obj)}
axios.post(url,QS.stringify(data)).then().catch()
参考文献
【1】四种常见的 POST 提交数据方式对应的content-type取值