beego 获取 axios 请求数据 | 臭大佬

臭大佬 2020-08-24 01:15:08 2846
Go 
简介 发现一个很奇怪的问题,`Beego`中用`GetString(key string) string`无法获取`Axios`请求数据。

开发环境

前端:Vue
后端:Beego

问题

发现一个很奇怪的问题,Beego中用GetString(key string) string无法获取Axios请求数据。

Beego中用GetString(key string) string获取请求参数,使用工具apizza(类似于postman的工具)发起请求,可以正常得到数据:

# admin.go 中接收数据的代码


func (self *AdminController) Login() {
    ...
    inputData := map[string]string{}

    inputData["username"] = username
    inputData["password"] = password
    // 返回参数
    self.ResJson(1, "获取数据", inputData, nil)

}

返回结果:

而当在前端使用axios传递参数时,发现无法获取:


前端代码之前是请求php获取数据,之前在php接口端是可以获取到请求参数的。这就很奇怪了,网上找了一圈都没有找到比较好的答案。在一个帖子里面看到,ajaxaxios请求数据的格式是不同的,然后特意写了个页面研究一下。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>请求方式对比</title> 
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
    var data =  {
        username: 'Fred',
        password: 'Flintstone'
    }
  $("#p1").click(function(){
    $.post("http://localhost:8181/api/admin/login",data,
    function(data,status){
        console.log(data);
    });
  });

  $("#p2").click(function(){
    axios.post('http://localhost:8181/api/admin/login',data
    )
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    });
  })
});
</script>
</head>
<body>
<p id="p1">ajax 请求</p>
<p id="p2">axios 请求</p>
</body>
</html>

上面的两个请求方式,发现ajax请求可以返回结果,而axios请求无法得到参数。

解决

默认情况下,jqueryajaxContent-Typeapplication/x-www-form-urlencoded

axios的话会做判断,如果data是字符串,Content-Typeapplication/x-www-form-urlencoded,如果data是对象,Content-Type是application/json

所以axios要和默认ajax请求一样,需要把datakey=value&key1=value1形式传递,同时,headerscontent-type参数修改为application/x-www-form-urlencoded

解决方案有两种,一种是在前端把axios参数修改为后端能够用GetString(key string) string获取得到的形式(ajax比较通用),二是后端做个兼容,既能接收ajax的参数,又能获取到axios请求的参数。

前端解决方案

需要修改的地方有两处,
1:参数以key=value&key1=value1形式传递;
2:headerscontent-type参数修改为application/x-www-form-urlencoded

axios.post('http://localhost:8181/api/admin/login',
'username=ssss&password=12345', {
        headers: {'content-type':'application/x-www-form-urlencoded'}
    })
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    });

后端解决方案

在配置文件app.conf中加上如下代码:

# 获取ajax提交的json数据,不然全是空的
copyrequestbody = true

GetString接收常规参数,用json接收axios传递的参数,获取参数代码如下:


// 如果参数名和模型中的字段相同,可以用模型 struct 代替
type InputData struct {
    Username string
    Password string
}

//用户登录
func (self *AdminController) Login() {
    var Input InputData
    // 获取字符串形式的参数,用于ajax
    username := self.GetString("username")
    password := self.GetString("password")

    if username == "" && password == "" {
        // 获取 axios 传递的参数
        data := self.Ctx.Input.RequestBody
        err := json.Unmarshal(data, &Input)
        if err != nil {
            self.ResJson(1, "存入失败", err.Error(), nil)
        }
        username = Input.Username
        password = Input.Password
    }
    //...

}
注意,前后端方案只需要改其中一个,不需要两边都进行修改。