用Go发送JSON请求需定义导出结构体并加json标签,用json.Marshal序列化,通过http.NewRequest构造POST请求并设Content-Type为application/json,再用http.Client发送,读取响应并解析。

用 Go 发送 JSON 请求很简单,核心是把结构体序列化为 JSON,再通过 http.Client 发起 POST(或其他方法)请求,同时设置正确的请求头。
定义结构体并导出字段
Go 的 json.Marshal 只能序列化首字母大写的导出字段。记得加 JSON 标签来控制键名:
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Age int `json:"age"`
}使用示例:
- 字段名小写(如
name)不会被序列化 → 必须大写开头(Name) -
json:"name"决定最终 JSON 中的字段名,不加标签则默认用结构体字段名 - 空值处理可用
omitempty,例如Phone string `json:"phone,omitempty"`
构造请求体并设置 Header
把结构体转成 JSON 字节流,作为请求体,并显式设置 Content-Type: application/json:
立即学习“go语言免费学习笔记(深入)”;
user := User{Name: "张三", Email: "zhang@example.com", Age: 28}
jsonData, err := json.Marshal(user)
if err != nil {
log.Fatal(err)
}
req, err := http.NewRequest("POST", "https://www.php.cn/link/93a819cbd635bd1505ef0f804c21cc2a", bytes.NewBuffer(jsonData))
if err != nil {
log.Fatal(err)
}
req.Header.Set("Content-Type", "application/json")
注意:
- 别忘了
bytes.NewBuffer(jsonData)把字节切片包装成io.Reader - Header 必须手动设置,标准库不会自动加
Content-Type - 如果需要认证,可追加:
req.Header.Set("Authorization", "Bearer xxx")
发送请求并读取响应
用默认或自定义的 http.Client 发送,检查状态码,再解析响应体:
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
log.Fatalf("HTTP error: %d", resp.StatusCode)
}
body, _ := io.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
fmt.Printf("Response: %+v\n", result)
常见做法:
- 用
io.ReadAll一次性读完响应体,避免残留 - 根据 API 返回结构,定义对应响应结构体更安全(比
map[string]interface{}类型强) - 生产环境建议设置超时:
&http.Client{Timeout: 10 * time.Second}
封装成可复用函数
把重复逻辑抽出来,提升可读性和复用性:
func PostJSON(url string, payload interface{}) (*http.Response, error) {
jsonData, err := json.Marshal(payload)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
return &http.Client{Timeout: 5 * time.Second}.Do(req)}
调用示例:
resp, err := PostJSON("https://www.php.cn/link/93a819cbd635bd1505ef0f804c21cc2a", User{
Name: "李四",
Email: "li@example.com",
Age: 30,
})
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()这样后续只需关注业务数据,不用每次写样板代码。










