前提
前端的登录,使用 axios 将用户信息使用 post 方式提交的后端
使用技术
问题
在使用 axios 的 post 方法向后台传递数据时,后台显示 null
解决
解析
前端
axios.post(’/login’, {
username: "小猪佩奇"
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
后端
@RequestMapping("/login")
@ResponseBody
public String login(String username) {
System.out.println(username);
return username;
}
看起来好像可以接收到数据,并将数据返回到前端。但在实际测试中却发现了拦截器拦截到了请求,但是却没有捕获数据,显示为 null
这令我百思不得姐,原以为是我的前端代码写的有问题,于是修改了一下,却还是得到了一个 null 的回答
axios({
method: 'post',
url: '/login',
data: {
username: '小猪佩奇'
}
})
为了确保不是我后端代码的原因,我使用了 postman 做了测试
postman 测试成功,有返回数据,并且 IDEA 控制台也输出了传来的数据,这就表明,不是后端代码的原因,那么错误可能就出现在 axios 上了。
于是我百度了 axios post 的工作过程,发现了一个非常严重的地方。axios 默认提交数据会使用 application/json 的方式,如果使用这种编码方式,那么传递到后台的将是序列化后的 JSON 字符串。所以前端接收到的数据就是这样的 “{ username: "小猪佩奇"}”,如果使用 application/x-www-form-urlencoded 上传数据是以键值对的形式传输(key-value)。
那为什么在使用 get 方法的时候却不会出错呢?
因为在执行 get 时,参数和值都是直接绑定在 url 上,所以即使不指定 content-type 也不影响后端读取数据,毕竟数据都在 url 上。
解决办法
URLSearchParams
采用formData的形式将数据提交到后端,效果最好,也很省事,推荐使用这种
let params = new URLSearchParams();
params.append("username", "小猪佩奇");
axios.post("/login", params);
但是不兼容IE,也算是一个小缺点吧
@RequestBody
使用requestBody注解可以处理applicaition/json数据,可以通过requestBody注解将请求中的json绑定到响应的参数中,并且可以对bean绑定。也就是说,我们可以通过这种方式获取数据
@RequestMapping("/login")
@ResponseBody
public String login(@RequestBody String username) {
System.out.println(username);
return username;
}
获取到的数据 > {"username":"小猪佩奇"},是不是和Map很像。我们将参数修改一下,使用map接收前端数据
@RequestMapping("/login")
@ResponseBody
public String login(@RequestBody Map map) {
String username = (String) map.get("username");
System.out.println(username);
return username;
}
这种方式适合参数比较多的情况下
Qs
因为我采用的是单文件模式,所以无法使用Qs
这里采用了网上的方式qs.stringify(data)