其实这个还是蛮简单的,初学时犯的错误,当时还是不太理解gin框架的整体流程
问题的发现:
| engine.POST("/login", func(c *gin.Context) { c.JSON(http.StatusOK, c.Request.PostForm) })
|
请求、响应报文(报文都略有删减)如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| POST /login?userid=123 HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 31 Connection: keep-alive
username=user&password=password
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Content-Length: 5
null
|
按理来说我们应该接收这样的报文:
1 2 3 4 5
| HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Content-Length: 46
{"password":["password"],"username":["user"]}
|
我其实挺疑惑的,接着我通过message := c.PostForm("message")
获取参数打印出来,代码如下:
1 2 3 4 5
| engine.POST("/login", func(c *gin.Context) { fmt.Println(c.PostForm("username")) fmt.Println(c.PostForm("password")) c.JSON(http.StatusOK, c.Request.PostForm) })
|
然后,就成功了??????报文很正常的打印出了我们想要的结果,(黑人问号.jpg)
很自然的我们就想到了c.PostForm("")
的副作用"解析"了c.Request.PostForm
,使得我们使用时有数据,我们来验证一下:
1 2 3 4 5 6 7 8 9 10 11
| engine.POST("/login", func(c *gin.Context) { fmt.Println(c.Request.PostForm) fmt.Println(c.PostForm("username")) fmt.Println(c.Request.PostForm) c.JSON(http.StatusOK, c.Request.PostForm) })
|
结果显示确实如此,这条c.PostForm
语句仿佛有魔力一样"解析了"报文,使得c.Request.PostForm
里面填充了数据,实际上c.Request.FormValue()
也有这种魔力。我们拨开迷雾去寻找真相吧。我们首先分析c.PostForm
这个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| func (c *Context) PostForm(key string) string { value, _ := c.GetPostForm(key) return value }
func (c *Context) GetPostForm(key string) (string, bool) { if values, ok := c.GetPostFormArray(key); ok { return values[0], ok } return "", false }
func (c *Context) GetPostFormArray(key string) ([]string, bool) { c.getFormCache() if values := c.formCache[key]; len(values) > 0 { return values, true } return []string{}, false }
func (c *Context) getFormCache() { if c.formCache == nil { c.formCache = make(url.Values) req := c.Request if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil { if err != http.ErrNotMultipart { debugPrint("error on parse multipart form array: %v", err) } } c.formCache = req.PostForm } }
func (r *Request) ParseMultipartForm(maxMemory int64) error { if r.MultipartForm == multipartByReader { return errors.New("http: multipart handled by MultipartReader") } if r.Form == nil { err := r.ParseForm() if err != nil { return err } } ... }
|
最后让我们测试一下:
1 2 3 4 5 6 7 8 9 10 11
| engine.POST("/login", func(c *gin.Context) { fmt.Println(c.Request.PostForm) _ = c.Request.ParseForm() fmt.Println(c.Request.PostForm) c.JSON(http.StatusOK, c.Request.PostForm) })
|