go 的 http.request.header 设了没生效,因默认 header 不可写且 host、content-length 等由 go 自动管理;须用 req.header.set() 设置,host 字段需改 req.host;authorization 等注意大小写与格式;content-type 必须匹配 body 类型;代理或 http/2 可能过滤非标准 header。

Go 的 http.Request.Header 为什么设了没生效?
因为 http.NewRequest 返回的 *http.Request 默认不带可写 Header,且部分 Header(如 Host、Content-Length)被 Go 自动管理,手动设置会被忽略或覆盖。
- 必须用
req.Header.Set("Key", "Value"),不能直接赋值req.Header["Key"] = []string{"Value"}(虽语法合法但可能被后续逻辑绕过) -
Host字段要改,得用req.Host = "example.com",而不是塞进Header - 如果用了
http.DefaultClient.Do(req),确保req.URL是完整 URL(含 scheme 和 host),否则Host可能被自动推导并覆盖你的设置
设置 Authorization 或自定义 Token 头的正确姿势
常见错误是拼错键名(比如写成 "authorization" 小写)或漏掉前缀(如 Bearer 后少空格),导致服务端 401。
- 标准写法:
req.Header.Set("Authorization", "Bearer <code>token") - 若用 API Key:
req.Header.Set("X-API-Key", "<code>your_key"),注意大小写敏感,服务端通常严格匹配 - 避免在 Header 中传敏感信息(如明文密码),Token 应已由上游签发好
POST 请求里 Content-Type 和 Body 的配合问题
设了 Content-Type: application/json 却发了表单数据,或者没设类型却发 JSON,后端解析会失败或降级为 raw body。
- JSON 请求:先
jsonBytes, _ := json.Marshal(data),再req.Header.Set("Content-Type", "application/json"),最后用bytes.NewReader(jsonBytes)构造Body - 表单请求:
req.Header.Set("Content-Type", "application/x-www-form-urlencoded"),Body 用strings.NewReader("a=1&b=2") - 别依赖
http.Post简化版——它不让你设 Header,必须用http.NewRequest+http.DefaultClient.Do
HTTP/2 和代理环境下 Header 被静默过滤的风险
某些反向代理(如 Nginx)、CDN 或 HTTP/2 实现会主动 strip 掉非标准或下划线开头的 Header(如 X-User-ID 没事,X_Internal_ID 可能被删)。
- 优先用 RFC 标准头名,或至少避免下划线(改用短横线,如
X-Internal-Id) - 测试时用
curl -v对比 Go 客户端和 curl 发出的原始请求,确认 Header 真的到了服务端 - 如果必须传内部字段,考虑放在 URL query 或加密后的 JSON body 里,别强依赖 Header
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











