本文详解 Go 语言中解析不同格式请求体(URL-encoded 和 JSON)的正确方法,包括使用 r.FormValue 提取表单字段、用 json.Decoder 解析 JSON 数据,并提供可运行示例与关键注意事项。
本文详解 go 语言中解析不同格式请求体(url-encoded 和 json)的正确方法,包括使用 `r.formvalue` 提取表单字段、用 `json.decoder` 解析 json 数据,并提供可运行示例与关键注意事项。
在 Go 的标准 net/http 包中,没有类似 Express.js 中开箱即用的 req.body 自动解析机制。请求体(request body)需根据其 Content-Type 手动解析。以下是两种最常见场景的处理方式:
✅ 场景一:表单提交(application/x-www-form-urlencoded)
当客户端以 AJAX 发送 URL 编码数据(如 fetch('/api/on', { method: 'POST', body: new URLSearchParams({url: 'https://example.com'}) })),服务端应先调用 r.ParseForm()(或直接使用 r.FormValue,它会自动触发解析),再通过键名获取值:
http.HandleFunc("/api/on", func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// 自动解析表单(支持 POST 表单和 query string)
url := r.FormValue("url") // 等价于 req.body.url 在 Express 中的行为
if url == "" {
http.Error(w, "Missing 'url' field", http.StatusBadRequest)
return
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
w.WriteHeader(http.StatusOK)
w.Write([]byte("Received URL: " + url))
})⚠️ 注意:r.FormValue 仅适用于 application/x-www-form-urlencoded 和 multipart/form-data(且后者需额外调用 ParseMultipartForm)。对纯 JSON 请求无效。
✅ 场景二:JSON 请求(application/json)
若前端发送的是 JSON(如 fetch('/api/on', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({url: 'https://example.com'}) })),则必须显式解码:
type RequestPayload struct {
URL string `json:"url"`
}
http.HandleFunc("/api/on", func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" || r.Header.Get("Content-Type") != "application/json" {
http.Error(w, "Only POST with application/json allowed", http.StatusUnsupportedMediaType)
return
}
var payload RequestPayload
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&payload); err != nil {
http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest)
return
}
defer r.Body.Close() // 始终关闭 Body,避免资源泄漏
// 使用 payload.URL
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "ok", "received_url": payload.URL})
})? 关键点:
- 必须检查 Content-Type 并使用 json.Decoder;
- r.Body 是 io.ReadCloser,解码后务必 defer r.Body.Close();
- 使用结构体标签(如 `json:"url"`)确保字段名映射准确;
- 错误处理不可省略——空 body、非法 JSON、字段缺失均会导致 Decode 返回非 nil error。
? 总结
Go 不提供自动化的 req.body 对象,但提供了更明确、更可控的数据解析路径:
- 表单数据 → r.FormValue("key")(简洁安全);
- JSON 数据 → json.NewDecoder(r.Body).Decode(&v)(类型安全、内存高效);
- 其他格式(如 XML、Protobuf)需选用对应解码器。
始终校验请求方法、Content-Type 和解码错误,并合理设置 CORS 头(如示例所示),即可稳健替代 Express 中的 req.body.url 行为。


















