go语言用http.get发get请求最简写法是直接调用http.get,适合快速测试;但生产环境必须用自定义http.client配置超时、header、连接池,并手动关闭resp.body、检查statuscode。

Go语言用http.Get发GET请求最简写法
直接调用http.Get就能发基础GET请求,但它内部会自动创建默认的http.Client和http.Transport,适合快速测试或低频调用。注意它不支持设置超时、自定义Header、重试等——一旦需要这些,就得换用http.Client。
常见错误:把http.Get当万能接口用,结果在生产环境遇到连接卡死、DNS缓存不更新、无超时导致goroutine堆积。
-
http.Get返回*http.Response和error,必须检查err,否则404、502等HTTP状态码不会触发error,得手动读resp.StatusCode - 响应体
resp.Body必须显式Close(),否则连接不会释放,容易触发too many open files - 它不支持重定向控制(比如禁用重定向),也不支持Cookie管理
用http.Client发GET并控制超时和Header
真正写接口调用时,应该自己构造http.Client,尤其是必须设Timeout。Go标准库的http.DefaultClient没有设超时,线上服务一卡就是几分钟。
示例代码片段:
client := &http.Client{
Timeout: 10 * time.Second,
}
req, _ := http.NewRequest("GET", "https://api.example.com/v1/users", nil)
req.Header.Set("User-Agent", "MyApp/1.0")
req.Header.Set("Authorization", "Bearer abc123")
<p>resp, err := client.Do(req)
if err != nil {
// 网络层错误:连接超时、DNS失败等
}
defer resp.Body.Close() // 必须放在这里,不是在err之后</p><p>if resp.StatusCode != 200 {
// HTTP状态码错误,比如401、404,此时err为nil
}</p>
-
http.Client.Timeout控制整个请求生命周期(DNS + 连接 + TLS握手 + 写请求 + 读响应头 + 读响应体),不是仅连接超时 - 如果需要更细粒度控制(如单独设连接超时),得配置
http.Transport,再赋给Client.Transport -
req.Header.Set比req.Header.Add更安全,避免重复Header
POST接口怎么发?别只记http.Post
http.Post看起来方便,但它的签名是func Post(url, contentType string, body io.Reader) (resp *Response, err error),无法设Header、无法控制重定向、无法复用连接——它只是http.DefaultClient.Post的封装,和http.Get一样不适用于生产。
正确做法:统一走http.NewRequest + client.Do,方法名、Body、Header全可控。
- JSON POST示例:
jsonBytes, _ := json.Marshal(map[string]string{"name": "foo"}),然后bytes.NewReader(jsonBytes)作body - Content-Type必须手动设:
req.Header.Set("Content-Type", "application/json"),http.Post虽能传contentType参数,但Header其他字段就束手无策 - 表单提交用
url.Values{"key": {"value"}}.Encode(),Header设application/x-www-form-urlencoded
接口返回JSON怎么解析?别漏掉io.ReadAll
很多人直接对resp.Body做json.NewDecoder(resp.Body).Decode(&v),这看似简洁,但一旦JSON格式错误或网络中断,Decode可能只读部分数据,导致后续读取resp.Body拿到空内容或错位字节——尤其当你还想记录原始响应日志时,Body已被消费完。
- 稳妥做法:先
bodyBytes, err := io.ReadAll(resp.Body),再json.Unmarshal(bodyBytes, &v) - 这样既能多次使用
bodyBytes(比如打日志、重试、审计),也能准确判断解析失败是网络问题还是JSON语法问题 - 注意
io.ReadAll会把整个响应体读进内存,大文件响应需改用流式处理(如json.NewDecoder配合限速Reader)
实际写接口时,最常被跳过的其实是resp.Body.Close()和超时配置;这两点不出问题时不显眼,一出就是连接耗尽或服务假死。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











