查询参数
?key=xxx&name=xxxx&name=yyyy 这种就被称为查询参数
查询参数不是GET请求专属的
name := c.Query("name")
age := c.DefaultQuery("age", "25")
keyList := c.QueryArray("key")
fmt.Println(name, age, keyList)例如请求 ?name=gin&age=123&key=123&key=124,输出为:
gin 123 [123 124]动态参数
用户的个人信息页面,他的路径
/users?id=123 // 查询参数的模式
/users/123 // 动态参数模式r.GET("users/:id", func(c *gin.Context) {
userID := c.Param("id")
fmt.Println(userID)
})表单参数
一般就是专指form表单
name := c.PostForm("name")
age, ok := c.GetPostForm("age")
fmt.Println(name)
fmt.Println(age, ok)文件上传
r.POST("users", func(c *gin.Context) {
fileHeader, err := c.FormFile("file")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(fileHeader.Filename) // 文件名
fmt.Println(fileHeader.Size) // 文件大小,单位是字节
file, _ := fileHeader.Open()
byteData, _ := io.ReadAll(file)
err = os.WriteFile("xxx.jpg", byteData, 0666)
fmt.Println(err)
})还有一种简单方式
err = c.SaveUploadedFile(fileHeader, "uploads/xxx/yyy/"+fileHeader.Filename)
fmt.Println(err)多文件上传
r.POST("users", func(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
fmt.Println(err)
return
}
for _, headers := range form.File {
for _, header := range headers {
c.SaveUploadedFile(header, "uploads/"+header.Filename)
}
}
})关于接口测试工具
postman
apifox
注意:接口测试工具能走通的,前端请求不一定可以走通
get请求带请求体
ws加请求头
原始内容
不同的请求体对应的原始内容
body阅后即焚问题解决
byteData, _ := io.ReadAll(c.Request.Body)
fmt.Println(string(byteData))
// 读了之后,body就没了,阅后即焚
c.Request.Body = io.NopCloser(bytes.NewReader(byteData))form-data
----------------------------853882779395683818968400
Content-Disposition: form-data; name="name"
gin
----------------------------853882779395683818968400
Content-Disposition: form-data; name="age"
1234
----------------------------853882779395683818968400--对应的分隔符就是
Content-Type:[multipart/form-data; boundary=--------------------------052455317193517003536866]x-www-form-urlencoded
url编码
name=%E6%9E%AB%E6%9E%AB&age=1234json
{
"name": "gin",
"age": 23
}