本文详解 Go 程序批量请求 Hacker News API 时出现 `EOF json` 错误的根本原因——HTTP 连接复用与服务端异常关闭的冲突,并提供两种可靠解决方案:手动设置 `Request.Close = true` 或配置 `Transport.DisableKeepAlives`,确保 JSON 解析稳定。
Go 默认使用 HTTP/1.1 的持久连接(Keep-Alive),客户端会复用 TCP 连接以提升性能。然而,Hacker News 的 API 服务器在返回响应后静默关闭连接,却未发送标准的 Connection: close 响应头。这导致 Go 的 http.Client 在后续请求中尝试复用已被对端关闭的连接,读取时触发 EOF,进而使 json.Unmarshal 失败(表现为 invalid character ‘\x00’ looking for beginning of value 或类似 EOF 相关错误)。
✅ 推荐解决方案一:显式关闭单次请求连接
修改 get() 函数,不依赖默认客户端行为,而是构造自定义 *http.Request 并设置 req.Close = true:
func get(url string) ([]byte, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
req.Close = true // 强制本次请求后关闭连接
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close() // 注意:务必关闭响应体
return io.ReadAll(res.Body) // 替换已弃用的 ioutil.ReadAll
}
? 提示:io/ioutil.ReadAll 自 Go 1.16 起已弃用,请使用 io.ReadAll(需导入 “io” 包)。
✅ 推荐解决方案二:全局禁用 Keep-Alive(适合高频批量请求)
若程序中大量调用外部 API,可创建专用 http.Client,禁用连接复用: