You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang中http.Client.Do响应未读响应体是否需调用Close?

问题解答:Go中使用http.Client.Do后,不读取响应体仍需调用response.Body.Close()吗?

嘿,这个问题其实是Go HTTP客户端使用中很容易踩的坑,我来给你掰扯清楚:无论你要不要读取响应体,都必须调用response.Body.Close(),原因主要有这几点:

  • 连接池复用的关键:Go的HTTP客户端默认启用了HTTP/1.1的持久连接(连接池),如果不关闭响应体,这条连接会被一直占用,无法放回连接池供后续请求复用。时间一长,连接池耗尽后新请求就会被迫创建新连接,甚至出现连接超时、资源耗尽的问题。
  • 避免资源泄漏:即使你只关心状态码和Cookie,服务器可能还在向客户端发送响应体数据,客户端会为这些数据分配缓冲区等内存资源。如果不调用Close,这些资源不会被及时回收,会造成内存泄漏,尤其在高频请求场景下影响很大。
  • HTTP协议的规范要求:从HTTP协议层面来说,客户端需要完整处理响应的所有部分,关闭Body是完成这个流程的必要步骤,确保连接状态的正确收尾。

给你一个正确的代码示例,即使只取状态码和Cookie也要记得Close:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://example.com", nil)
    if err != nil {
        log.Fatalf("创建请求失败: %v", err)
    }

    resp, err := client.Do(req)
    if err != nil {
        log.Fatalf("发起请求失败: %v", err)
    }
    // 一定要用defer确保Body被关闭,即使后续代码出错也能执行
    defer resp.Body.Close()

    // 只提取你需要的状态码和Cookie
    statusCode := resp.StatusCode
    cookies := resp.Cookies()

    fmt.Printf("状态码: %d\n", statusCode)
    fmt.Println("Cookie列表:")
    for _, cookie := range cookies {
        fmt.Printf("  %s: %s\n", cookie.Name, cookie.Value)
    }
}

顺便提一句:哪怕你确实完全不需要响应体,也不用先去读取它再Close,直接调用resp.Body.Close()就足够了——这个方法内部会处理未读取的数据流,确保连接和资源被正确释放。

内容的提问来源于stack exchange,提问作者zer09

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:43:46