[Go] 禁止 net/http 包中 http.Client 的自动重定向
Go 语言标准库的 net/http 包中的 http.Client 默认会自动跟随(follow)重定向,大多数时候,这种自动化的跟随是有意义的。比如:自动把 HTTP 连接重定向到 HTTPS 连接。 但是,也有很多时候这种自动重定向会带来麻烦,或是不必要。比如:常用的模拟 POST 登录方式。
常见的 POST 登录方式
- 浏览器
POST /login
- 服务器返回
302 Found
,并携带 Cookie 和新的登录后的页面/index
- 浏览器重新发起到
/index
的请求
如果直接使用 http.Post
并登录成功的话,最终的页面是/index
,中间的重定向相关的数据是拿不到的,包括 Cookie!
而我最近刚做一个命令行的路由器客户端,它就需要将上面过程中第二步返回的 Cookie 拿到,并用作后续 API 请求的验证。 所以,得想办法禁止 http.Client 的自动重定向。
http.Client 中的重定向
http.Client
中有一个跟重定向相关的字段CheckRedirect:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
从注释来看,这是一个函数字段,用于指定处理重定向的策略:
-
如果这个字段不为空,Client将在每次重定向之前先调用它。如果这个函数返回了一个特殊的ErrUseLastResponse错误(Go1.7引入),那么将使用最近一次的请求响应作为返回;
1 2 3 4 5 6
// Sentinel error to let users select the // previous response, without closing its // body. See Issue 10069. if err == ErrUseLastResponse { return resp, nil }
-
如果这个字段为空,Client 将采用默认的重定向策略:将在最多连续重定向 10 次后停止;
如何禁止重定向
不使用默认的 http.Get
、http.Post
等方法,而是自定义一个带不重定向功能的 Client:
1 2 3 4 5 |
|
然后调用 client 的 client.Get
、client.Post
、client.Do
等方法即可。