必须手动构造*http.Request并用req.Header.Set添加Header,http.Post无法自定义Header;需设Content-Type为application/json; charset=utf-8,Body须经json.Marshal序列化,Client须配置Timeout和CheckRedirect以保障生产环境可靠性。
用 http.NewRequest 构造带 Header 的请求体
go 标准库不提供“一键加 header 的 post”函数,必须手动构造 *http.request。直接调用 http.post 会丢失 header 控制权,它内部用的是默认空 header。
正确做法是先用 http.NewRequest 创建请求,再通过 req.Header.Set 或 req.Header.Add 注入字段:
req, err := http.NewRequest("POST", "https://api.example.com/v1/data", strings.NewReader(`{"id":123}`))
if err != nil {
log.Fatal(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer abc123")
req.Header.Set("X-Client-ID", "myapp-v2")
注意:Set 会覆盖同名 Header,Add 允许重复(如多个 Cookie),按需选择。
发送前检查 Content-Length 是否被自动设置
如果请求 Body 是 strings.NewReader 或 bytes.Reader 这类已知长度的类型,http.DefaultClient.Do 会自动计算并设置 Content-Length —— 你不需要、也不该手动设它。
但如果你用 bytes.Buffer 或自定义 io.Reader(比如从文件读),且未实现 Len() 方法,Go 会退回到 Transfer-Encoding: chunked,某些老旧服务(如部分 PHP 后端)可能不兼容。
避免意外的方式:
- 优先用
strings.NewReader或bytes.NewReader(它们有Len()) - 若必须用
bytes.Buffer,发送前显式调用buf.Len()验证非零 - 不要手动写
req.Header.Set("Content-Length", "...")—— 容易出错且可能被 client 覆盖
处理 JSON Body 时别漏掉 Content-Type
很多接口只认 application/json; charset=utf-8,而只写 application/json 在某些严格网关下会被拒绝。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
更稳妥的写法是:
req.Header.Set("Content-Type", "application/json; charset=utf-8")
另外,如果 Body 是结构体,记得用 json.Marshal 编码后再传入 strings.NewReader,别直接传 struct 指针——否则发出去的是 Go 内存地址字符串,不是 JSON。
超时与重定向需单独配置 http.Client
http.DefaultClient 没有设置超时,一旦后端卡住或 DNS 不响应,请求会 hang 住直到系统级 TCP 超时(通常几分钟)。生产环境必须自定义 client:
client := &http.Client{
Timeout: 10 * time.Second,
}
resp, err := client.Do(req)
如果目标接口会 302 重定向,DefaultClient 默认跟随(最多 10 次),但重定向后原始 Header 会丢失。需要保留 Header 的话,得自己实现 CheckRedirect 回调,或者干脆禁用重定向:
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse // 禁用自动跳转
},
}
Header 的传递逻辑在重定向中不是透明的,这点容易被忽略,尤其当调试“为什么第二跳没认证头”时。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










