这两天在开发项目的时候遇到了一个问题,请求了一个URL,它会302到另一个地址,本意上只是想检查这个URL是否会做3XX的redirect跳转,结果每次reqeust都会返回最后一跳的结果。后来就看了下源码,了解下请求跳转的机制
实现代码
看下实现的简单代码
func main() { client := &http.Client{} url := "http://www.qq.com" reqest, err := http.NewRequest("GET", url, nil) if err != nil { panic(err) } response, _ := client.Do(reqest) fmt.Println(response.Status) } curl http://www.qq.com <html> <head><title>302 Found</title></head> <body bgcolor="white"> <center><h1>302 Found</h1></center> <hr><center>stgw/1.3.12.4_1.13.5</center> </body> </html>
我们知道在浏览器里面输入http://www.qq.com会302跳转到https://www.qq.com。我们使用curl可以看到使用302的跳转。
可是我只想获取第一跳的的response 的状态码。发现没法实现了,所以看了下源码。
http请求为什么可以做到多次redirect
看了下 client.Do 源码实现
607 err = c.checkRedirect(req, reqs)
代码的上下文,可以看出 req是将要请求的request,reqs已经请求过的request
主要看下checkRedirect
func (c *Client) checkRedirect(req *Request, via []*Request) error { fn := c.CheckRedirect if fn == nil { fn = defaultCheckRedirect } return fn(req, via) }
可以看到如果设置了checkRedirect就执行checkRedirect,如果没有设置就执行 defaultCheckRedirect。
再看下 defaultCheckRedirect
func defaultCheckRedirect(req *Request, via []*Request) error { if len(via) >= 10 { return errors.New("stopped after 10 redirects") } return nil }
可以看到最多可以redirect 10次,如果大于10的跳转就抛出错误结束这次请求了。
大体上流程已经搞明白。只要设置checkRedirect返回error,理论上就能实现只请求一次的目的。
func main() { client := &http.Client{} url := "http://www.qq.com" reqest, err := http.NewRequest("GET", url, nil) if err != nil { panic(err) } client.CheckRedirect = func(req *http.Request, via []*http.Request) error { return fmt.Errorf("first response") } response, _ := client.Do(reqest) fmt.Println(response.StatusCode) } /private/var/folders/4h/lrsc4fyd12v9ctl31ggk5ckc0000gp/T/___go_build_main_go #gosetup 302
基本实现了。
其实,在CheckRedirect方法上面有一行说明,
ErrUseLastResponse can be returned by Client.CheckRedirect hooks to control how redirects are processed. If returned, the next request is not sent and the most recent response is returned with its body unclosed.
Client.CheckRedirect挂钩可以返回ErrUseLastResponse,以控制如何处理重定向。 如果返回,则不发送下一个请求,并且返回最近的响应且其主体未关闭。
可以看到返回 ErrUseLastResponse是官方的建议的设置
最终的代码实现应该是这样的。
func main() { client := &http.Client{} url := "http://www.qq.com" reqest, err := http.NewRequest("GET", url, nil) if err != nil { panic(err) } client.CheckRedirect = func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse } response, _ := client.Do(reqest) fmt.Println(response.StatusCode) }
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 证声音乐图书馆《夏至 爵士境地》[320K/MP3][70.37MB]
- 孙露《同名专辑》限量1:1母盘直刻[低速原抓WAV+CUE]
- 【宝丽金唱片】群星《鼓舞飞扬》WAV+CUE
- 莫扎特弗雷德沃夏克肖斯塔科维奇《钢琴五重奏》(DG24-96)FLAC
- 证声音乐图书馆《夏至 爵士境地》[FLAC/分轨][360.16MB]
- 证声音乐图书馆《日落琴声 x 弦乐》[320K/MP3][71.2MB]
- 证声音乐图书馆《日落琴声 x 弦乐》[FLAC/分轨][342.58MB]
- 谢采妘2011《难忘的旋律(Non-StopChaCha)》马来西亚版[WAV+CUE]
- 林翠萍《听见林翠萍,记忆就会醒来》2CD[WAV+CUE]
- 木村好夫《天龍HIFI木吉他、木村好夫精选好歌》日本天龙版[WAV整轨]
- 证声音乐图书馆《日出琴声 x 民谣》[320K/MP3][53.76MB]
- 证声音乐图书馆《日出琴声 x 民谣》[FLAC/分轨][239.29MB]
- 证声音乐图书馆《绿意森林·吉他絮语》[320K/MP3][65.77MB]
- 证声音乐图书馆《绿意森林·吉他絮语》[FLAC/分轨][295.2MB]
- 证声音乐图书馆《流动与延展 彼拉提斯》[320K/MP3][56.88MB]