
在 Go 的 net/http 客户端中,默认会自动跟随重定向直至最终状态码(如 200),但可通过自定义 CheckRedirect 函数中断重定向流程,从而捕获并返回首次 HTTP 响应(如 301、302 等)。
在 go 的 `net/http` 客户端中,默认会自动跟随重定向直至最终状态码(如 200),但可通过自定义 `checkredirect` 函数中断重定向流程,从而捕获并返回首次 http 响应(如 301、302 等)。
Go 的 http.Client 默认行为是自动处理最多 10 次重定向(3xx 状态码),并最终返回最终目标的响应。若需获取首次服务器响应(例如访问 https://apple.com 时的 301 Moved Permanently),必须显式禁用自动重定向。
核心方法是设置 Client.CheckRedirect 字段为一个返回 http.ErrUseLastResponse 的函数。该错误是 Go 标准库预定义的特殊哨兵错误,用于指示客户端停止重定向,并直接返回当前响应(即第一个非 2xx/3xx 终止前的响应)。
以下是完整示例代码:
package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
// 立即终止重定向,返回当前请求对应的响应
return http.ErrUseLastResponse
},
}
resp, err := client.Get("https://apple.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Printf("Status Code: %d %s\n", resp.StatusCode, resp.Status)
// 输出示例:Status Code: 301 Moved Permanently
// 可选:读取响应体(如需查看 Location 头)
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Response Body (first 200 chars): %s\n", string(body)[:min(200, len(body))])
}
func min(a, b int) int {
if a <p>⚠️ 注意事项:</p>
- http.ErrUseLastResponse 是唯一被 http.Client 识别为“终止重定向并返回当前响应”的标准错误;使用其他错误(如 fmt.Errorf("stop"))会导致整个请求失败并返回该错误,而非响应。
- 此方式仍会发起初始请求并接收首个响应,因此网络开销与 curl -I 相当,但不会发出后续跳转请求。
- 若需进一步控制(如仅拦截前 N 次重定向),可在 CheckRedirect 中检查 via 长度或 req.URL 进行条件判断。
- 对于 HEAD 请求,建议配合 resp.Header.Get("Location") 解析重定向目标,便于调试或链路分析。
通过此方案,你完全掌控重定向策略,精准获取服务端返回的第一个 HTTP 响应——无论是 301、302、404 还是 503,皆可原样捕获,满足监控、爬虫协议适配、SEO 分析等专业场景需求。











