
Go 的 http.Get 默认最多跟随 10 次重定向,超出即报 “stopped after 10 redirects” 错误;解决方法是创建自定义 http.Client 并设置 CheckRedirect 函数,以安全、可控地调整重定向策略。
go 的 `http.get` 默认最多跟随 10 次重定向,超出即报 “stopped after 10 redirects” 错误;解决方法是创建自定义 `http.client` 并设置 `checkredirect` 函数,以安全、可控地调整重定向策略。
在使用 Go 标准库发起 HTTP 请求时,http.Get() 是最简捷的方式,但它背后依赖的是默认配置的 http.DefaultClient。该客户端对重定向(301/302/303/307)有严格限制:最多连续跟随 10 次重定向,超过即返回错误(如 stopped after 10 redirects)。你遇到的 Wikipedia URL 报错,表面看是“链接跳转太多”,实则可能反映更深层问题——例如服务端重定向逻辑异常、客户端环境干扰(如代理、DNS 重定向、地域限流),甚至潜在的重定向循环。
⚠️ 重要前提:优先排查原因,而非盲目增加限制
Wikipedia 官方页面通常不会触发 10+ 次重定向。若频繁复现该错误,请先验证:
- 是否在受限网络环境(企业防火墙、教育网代理)中运行?
- 是否启用了中间人代理或调试工具(如 Fiddler、Charles)?
- 直接使用 curl -v https://en.wikipedia.org/wiki/List_of_S%26P_500_companies 观察实际跳转链路;
- 尝试更换 User-Agent(部分站点对无头客户端限流)。
✅ 若确认需放宽限制,应通过 http.Client 显式控制
不推荐修改标准库源码或滥用全局 http.DefaultClient。正确做法是构造独立 Client 实例,并通过 CheckRedirect 字段定义重定向策略:
package main
import (
"fmt"
"net/http"
"net/url"
"log"
)
func main() {
// 自定义 Client:允许最多 20 次重定向
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
// 可选:记录每次重定向(调试用)
fmt.Printf("Redirect %d: %s → %s\n", len(via), via[len(via)-1].URL, req.URL)
// 允许最多 20 次重定向;超限则终止
if len(via) >= 20 {
return fmt.Errorf("stopped after 20 redirects")
}
return nil // 继续跟随
},
}
resp, err := client.Get("https://en.wikipedia.org/wiki/List_of_S%26P_500_companies")
if err != nil {
log.Fatal("Request failed:", err)
}
defer resp.Body.Close()
fmt.Printf("Final status: %s (URL: %s)\n", resp.Status, resp.Request.URL)
}
? 关键要点说明:
- CheckRedirect 接收两个参数:req(即将发起的下一次请求)和 via(已执行的重定向请求切片,via[0] 是原始请求);
- 返回 nil 表示继续跟随,返回非 nil error 则中止并透出该错误;
- 可在回调中加入业务逻辑:例如拒绝跳转到非 HTTPS 域、拦截特定路径、添加请求头等;
- 永远避免返回 http.ErrUseLastResponse 以外的 error 时忽略重定向状态——这可能导致静默失败;
- 若需完全禁用重定向(如手动处理跳转),可直接返回 http.ErrUseLastResponse(此时响应体含 3xx 状态码及 Location 头)。
? 进阶建议:增强健壮性
结合超时、重试与 User-Agent 设置,构建生产级 HTTP 客户端:
client := &http.Client{
Timeout: 10 * time.Second,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if len(via) >= 15 { // 保守设为 15,留出安全余量
return fmt.Errorf("too many redirects: %d", len(via))
}
// 添加统一 User-Agent 避免被反爬拦截
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) Go-Client")
return nil
},
}
总之,重定向限制是 Go 设计的安全护栏,而非缺陷。合理利用 CheckRedirect 既能应对特殊场景,又能保持代码可维护性与可观测性。切记:调高阈值前,务必先理解为何发生高频跳转——它往往是系统异常的第一信号。











