在 Golang 中,获取 HTTP POST 请求的数据可以通过标准库 net/http
或 Web 框架(如 Gin、Echo)实现。以下是常见场景的示例:
1. 获取表单数据 (Form Data)
适用于 Content-Type: application/x-www-form-urlencoded
或 multipart/form-data
。
(1) 标准库 net/http
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
// 解析表单数据(必须先调用 ParseForm)
err := r.ParseForm()
if err != nil {
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
// 获取单个字段
name := r.Form.Get("name")
age := r.Form.Get("age")
// 直接访问 Form 对象(map类型)
fmt.Println("All form data:", r.Form)
fmt.Fprintf(w, "Name: %s, Age: %s", name, age)
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
(2) Gin 框架
r.POST("/form", func(c *gin.Context) {
name := c.PostForm("name")
age := c.DefaultPostForm("age", "18") // 带默认值
c.JSON(200, gin.H{
"name": name,
"age": age,
})
})
2. 获取 JSON 数据
适用于 Content-Type: application/json
。
(1) 标准库 net/http
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func handler(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
var user User
err = json.Unmarshal(body, &user)
if err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
fmt.Fprintf(w, "Name: %s, Age: %d", user.Name, user.Age)
}
(2) Gin 框架(推荐)
r.POST("/json", func(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{
"name": user.Name,
"age": user.Age,
})
})
3. 获取文件上传 (Multipart Form)
适用于 Content-Type: multipart/form-data
。
(1) Gin 框架示例
r.POST("/upload", func(c *gin.Context) {
file, header , err := c.Request.FormFile("file") // key为"file"
if err != nil {
c.String(http.StatusBadRequest, "Upload failed")
return
}
defer file.Close()
//保存文件到本地
dst := "./uploads/" + header.Filename
c.SaveUploadedFile(header , dst)
c.String(http.StatusOK,"Upload success")
})
4. RAW Body (原始数据流)
直接读取请求体:
bodyBytes , _ := io.ReadAll(r.Body )
defer r.Body.Close()
rawData:= string(bodyBytes )
注意事项:
- 必须关闭 Body:处理完请求后调用
r.Body.Close()
(或在 Go1.20+中会自动处理)。 - 多次读取问题:
r.Body
只能读取一次,如需复用可先保存到变量。 - 性能优化:对大文件上传使用流式处理,避免全量读取内存。
根据实际需求选择合适的方法!
内容由零声教学AI助手提供,问题来源于学员提问