登录
首页 >  Golang >  Go教程

Go语言发送GET请求教程

时间:2026-04-08 10:45:23 153浏览 收藏

本文深入剖析了Go语言中发送HTTP GET请求的正确实践,强调http.Get仅适用于简单测试,生产环境必须显式构建*http.Client并精细配置Timeout、MaxIdleConns、IdleConnTimeout等关键参数,同时严谨处理URL编码(务必使用url.Values.Encode而非字符串拼接)、状态码校验(不能仅依赖err判断)、响应体读取与关闭(避免连接泄露),以及连接复用与超时协同策略——任何一环疏忽都可能在线上引发静默故障,如连接耗尽、请求卡死或编码错误导致400响应。

Go语言如何发GET请求_Go语言HTTP GET请求教程【总结】

http.Get 发最简 GET 请求,但别直接用在生产环境

它确实能发请求,比如 resp, err := http.Get("https://api.example.com/data")

但实际用时会卡住、超时、无法设 Header、不能复用连接——因为 http.Get 内部用了默认的 http.DefaultClient,而它的 Timeout 是 0(无限等待),Transport 也没配连接池参数。

  • 必须显式构造 *http.Client,设好 Timeout
  • 如果要并发发大量请求,得配 MaxIdleConnsMaxIdleConnsPerHost,否则容易耗尽文件描述符
  • http.Get 返回的 resp.Body 必须手动 Close(),漏掉会泄露连接

GET 带 query 参数,别拼字符串,用 url.Values

手拼 "?q=hello&lang=zh" 看似快,但中文、特殊符号(如 &=)会出错,URL 编码漏掉就 400。

正确做法是用标准库生成:

values := url.Values{}
values.Set("q", "你好")
values.Set("page", "1")
u := &url.URL{
    Scheme: "https",
    Host:   "api.example.com",
    Path:   "/search",
    RawQuery: values.Encode(), // 自动编码
}
req, _ := http.NewRequest("GET", u.String(), nil)
  • url.Values.Encode() 保证所有值都按 RFC 3986 编码
  • 不要用 fmt.Sprintf 拼接,哪怕参数全是 ASCII 数字也不保险
  • 如果参数来自用户输入,更不能信任原始字符串

处理响应 Body 前,先检查 resp.StatusCode

很多人只判 err != nil,但 HTTP 状态码 4xx/5xx 不会触发 errresp 依然非 nil,Body 里可能是错误页 HTML 或 JSON 错误体。

  • 必须检查 resp.StatusCode >= 200 && resp.StatusCode < 300,或至少排除 4xx/5xx
  • io.ReadAll(resp.Body) 前一定要 defer resp.Body.Close(),否则连接不释放
  • 如果响应很大,别直接 ReadAll,考虑流式解析或设 LimitReader

自定义 Client 时,http.TransportIdleConnTimeout 很关键

默认 Transport 的 IdleConnTimeout 是 30 秒,短连接没问题;但高并发下,如果服务端 Keep-Alive 时间更短(比如 Nginx 默认 75 秒),客户端可能拿着过期连接重用,下次请求就卡住或报 EOF

  • IdleConnTimeout 小于服务端 Keep-Alive 时间(例如设为 60 秒)
  • 同时配 MaxIdleConns(全局)和 MaxIdleConnsPerHost(单域名),避免连接数爆炸
  • 调试时可临时加 ForceAttemptHTTP2: false 排查 HTTP/2 相关问题

HTTP 客户端不是“写完就跑”,连接生命周期、超时、编码、状态码这几块,漏一个就在线上安静地出问题。

以上就是《Go语言发送GET请求教程》的详细内容,更多关于的资料请关注golang学习网公众号!

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