登录
首页 >  Golang >  Go教程

Go语言发送POST请求教程

时间:2026-04-03 17:27:23 266浏览 收藏

本文深入解析了Go语言中发送POST请求的两种核心方式:简易但受限的`http.Post`仅适用于调试或简单表单/纯文本提交,而生产环境必须采用灵活可控的`http.NewRequest`配合`http.Client.Do`——它支持自定义Header(如JSON的Content-Type、认证Token)、连接复用、超时控制、文件上传(推荐标准库`mime/multipart`安全封装)以及健壮的错误处理与重试机制,同时警示了常见陷阱,如body重复读取、文件句柄泄漏、boundary遗漏和盲目panic等,为开发者提供从入门到落地的完整实践指南。

Go语言如何发POST请求_Go语言HTTP POST请求教程【进阶】

http.Post 发最简 POST,但只适合表单或纯文本

如果你只是想发一个 application/x-www-form-urlencoded 表单(比如登录),或者发一段纯文本,http.Post 确实最短——但它会强制设置 Content-Type,且无法自定义 header 或复用连接。

常见错误现象:http.Post 返回 415 Unsupported Media Type,因为服务端期待 application/json,而它却发了 application/x-www-form-urlencoded

实操建议:

  • 只在调试或一次性脚本中用 http.Post,例如:http.Post("https://api.example.com/login", "application/x-www-form-urlencoded", strings.NewReader("user=a&pass=b"))
  • 不要对 JSON、二进制、带认证头的请求用它
  • 它底层每次新建 http.Client,不复用 TCP 连接,高并发下性能差

真正可控的 POST:用 http.NewRequest + http.DefaultClient.Do

这才是生产环境的标准写法。你完全掌控 method、body、headers、timeout 和 client 复用。

关键点:

  • 必须手动调用 req.Header.Set("Content-Type", "...")http.NewRequest 不设默认值
  • body 参数要传 io.Reader,别直接传字符串——用 strings.NewReaderbytes.NewBuffer
  • 记得检查 resp.Body 是否为 nil,并用 defer resp.Body.Close()

示例(发 JSON):

data := map[string]string{"name": "foo"}
jsonBytes, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.example.com/users", bytes.NewBuffer(jsonBytes))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer xyz")
<p>client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()</p>

POST 文件上传:别手写 boundary,用 mime/multipart

手动拼 multipart/form-data body 容易出错(boundary 不一致、换行符不对、编码缺失),Go 标准库提供了安全封装。

容易踩的坑:

  • 忘记调用 w.Close() —— 导致 body 缺少结尾 boundary,服务端收不到完整数据
  • os.Open 打开文件后没 Close,造成文件句柄泄漏
  • Writer.WriteFieldWriter.CreateFormFile 的字段名必须和服务端约定一致(比如有的接口叫 file,有的叫 upload

实操建议:

  • bytes.Buffer 接收 multipart 写入,避免内存暴涨(大文件先流式上传)
  • 上传前检查文件大小,避免 OOM;必要时用 io.LimitReader

超时、重试、错误处理不能靠 log.Fatal

线上服务里,一次 POST 失败就 panic 是灾难。真实场景要考虑网络抖动、服务端 5xx、DNS 解析失败等。

关键配置项:

  • http.Client.Timeout:只控制整个请求生命周期,不区分连接、读、写
  • 更细粒度要用 http.Transport:设置 MaxIdleConnsMaxIdleConnsPerHostIdleConnTimeout
  • 重试逻辑必须判断错误类型:url.Error 中的 Timeout() 可重试,net.OpError 中的 DNS 错误通常也要重试,但 4xx 响应一般不该重试

复杂点在于:body 是 io.ReadCloser,一旦读过就不可重放。如果要重试,得提前把 body 缓存在 bytes.Buffer 或用 io.NopCloser(bytes.NewReader(buf.Bytes())) 重建。

终于介绍完啦!小伙伴们,这篇关于《Go语言发送POST请求教程》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>