让我感到遗憾的是,我一直无法弄清楚如何从Gin框架的前端获取数据。在Django中,我得到了数据,所以:
user=request.data.get('user')
print(user)
一切都是简单易懂的。 我应该怎么用杜松子酒做呢?
user := c.Query("user")
user := c.Param("user")
user := c.Params.ByName("user")
user := c.PostForm("user")
println(user)//emptiness....
答案 0 :(得分:1)
好吧,我想你应该读一本关于HTTP如何工作的书/ HOWTO,并花一些时间,因为它似乎是在试图消除手头的问题,而没有真正理解浏览器和后端之间发生了什么。服务。
这里的真正问题是,您似乎要意识到还有更多的运动部件,而前进的方式取决于您的前沿技术。
您没有完全告诉我们您的请求方式, 但从显示的征求意见中,您正在使用那种“ axios”的小气。 如果我设法正确搜索了该项目, 其自述文件states:
默认情况下,axios将JavaScript对象序列化为JSON。要改为以
application/x-www-form-urlencoded
格式发送数据,可以使用以下选项之一。
这意味着两件事:
axios.port
被认为执行了HTTP POST请求
其Content-Type
字段设置为application/json
及其有效载荷(如果愿意,也可以是“ body”)
{user:this.user}
JavaScript对象的JSON序列化。相反,您应该将传入请求的主体解释为JSON格式。我不知道如何在“ go-gin”中做到这一点,但是在简单的Go语言中,这就像
func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
var user User
dec := json.NewDecoder(req.Body)
err := dec.Decode(&user)
if err != nil {
rw.Header().Set("Content-Type", "text/plain; charset=UTF-8")
rw.WriteHeader(http.StatusBadRequest)
fmt.Fprintln(rw, "Error parsing request body: ", err)
return
}
}
理想情况下,您首先要检查传入请求的内容类型确实为application/json
,如果不是,则立即用http.StatusBadRequest
拒绝它。
一个工作代码的例子是
// VerifyContentTypeIsJSON makes sure the HTTP header of a server
// http.Request contains the Content-Type field and it indicates
// the request payload is JSON.
// The implementation is based on RFC 7231 (section 3.1.1.5) and RFC 8259.
func VerifyContentTypeIsJSON(header http.Header) error {
var s string
if values := header["Content-Type"]; len(values) > 0 {
s = values[0]
} else {
return errors.New("missing Content-Type")
}
if s == "" {
return errors.New("empty Content-Type")
}
if i := strings.IndexByte(s, ';'); i != -1 {
s = strings.TrimSpace(s[:i])
}
if strings.ToLower(s) != "application/json" {
return fmt.Errorf("unknown Content-Type: %v, must be application/json", s)
}
return nil
}
具有此功能,您将拥有类似的内容
defer req.Body.Close()
之后并进行实际解析:
if err := VerifyContentTypeIsJSON(req.Header); err != nil {
rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
rw.WriteHeader(http.StatusBadRequest)
fmt.Fprintln(rw, err)
return
}
(请注意,“ go-gin”可能与已经内置的功能类似,因此请检查此内容。)
User
类型应为某种struct
类型,以匹配要从请求中解组的JSON对象的形状。像这样:
type User struct {
User string `json:"user"`
}
在这两个地方,我的示例都没有返回一个 给用户的错误,它使用纯文本的内容类型 (采用UTF-8编码)。可能可以,但可能不行。 假设您的客户可能希望使用JSON格式的文档 同意的形状。
或者您可以使用content negotiation,但我建议您先弄简单一些的事情。
要检查的文献
HTTP POST
请求explained at MDN。也许可以回答您有关问题的那一部分 为什么它在Django中“有效”。 我只能猜测,但是我认为它只是实现了很多魔术,这些魔术看着传入的请求并尝试猜测如何从中提取数据。
问题在于猜测可能确实适用于 一次性的脚本,但是当您要实现类似Web API的东西时(很多都不太正确地称为“ REST”,但是请不要离题),最好 对端点接受的内容非常明确 精确以及它们对请求的响应方式-合法和格式错误。
关于Go中的魔术,您可以阅读this。
答案 1 :(得分:0)
在使用c.Request.ParseForm()
之前,您需要先致电request.Form
说here:
对于所有请求,ParseForm都会从URL解析原始查询并更新r.Form
对于其他HTTP方法,或者当Content-Type不是application / x-www-form-urlencoded时,不读取请求主体,并且r.PostForm初始化为非空值。
答案 2 :(得分:0)
如果您期望请求中包含JSON正文,则可以使用gin来做到这一点。为要从主体中抓取的数据创建一个结构。使用json
标签作为JSON密钥名称,除非您要将Go字段名称与它们完全匹配。然后在gin上下文中调用BindJSON
方法。
例如:
type User struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Login string `json:"login"`
}
func (h *Handler) HandleUser(gctx *gin.Context) {
user := new(User)
err := gctx.BindJSON(user)
if err != nil {
text := fmt.Sprintf("Failed to read user data from request: %s", err)
log.Error(text)
gctx.JSON(http.StatusBadRequest, gin.H{"error": text})
return
}
// do something with user
}
答案 3 :(得分:0)
服务器GIN无法处理来自axios的常规默认应用程序/ json请求!!!什么??? 请求应以application / x-www-form-urlencoded发送。 我在Vue项目中的决定: 使用vue-resource代替axios(axios.post => this。$ http.post)和选项 Vue.http.options.emulateJSON = true;在main.js中