這兩天在開發(fā)項目的時候遇到了一個問題,請求了一個URL,它會302到另一個地址,本意上只是想檢查這個URL是否會做3XX的redirect跳轉(zhuǎn),結(jié)果每次reqeust都會返回最后一跳的結(jié)果。后來就看了下源碼,了解下請求跳轉(zhuǎn)的機制
實現(xiàn)代碼
看下實現(xiàn)的簡單代碼
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跳轉(zhuǎn)到https://www.qq.com。我們使用curl可以看到使用302的跳轉(zhuǎn)。
可是我只想獲取第一跳的的response 的狀態(tài)碼。發(fā)現(xiàn)沒法實現(xiàn)了,所以看了下源碼。
http請求為什么可以做到多次redirect
看了下 client.Do 源碼實現(xiàn)
607 err = c.checkRedirect(req, reqs)
代碼的上下文,可以看出 req是將要請求的request,reqs已經(jīng)請求過的request
主要看下checkRedirect
func (c *Client) checkRedirect(req *Request, via []*Request) error {
fn := c.CheckRedirect
if fn == nil {
fn = defaultCheckRedirect
}
return fn(req, via)
}
可以看到如果設(shè)置了checkRedirect就執(zhí)行checkRedirect,如果沒有設(shè)置就執(zhí)行 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的跳轉(zhuǎn)就拋出錯誤結(jié)束這次請求了。
大體上流程已經(jīng)搞明白。只要設(shè)置checkRedirect返回error,理論上就能實現(xiàn)只請求一次的目的。
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
基本實現(xiàn)了。
其實,在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,以控制如何處理重定向。 如果返回,則不發(fā)送下一個請求,并且返回最近的響應(yīng)且其主體未關(guān)閉。
可以看到返回 ErrUseLastResponse是官方的建議的設(shè)置
最終的代碼實現(xiàn)應(yīng)該是這樣的。
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)
}
到此這篇關(guān)于詳解golang開發(fā)中http請求redirect的問題的文章就介紹到這了,更多相關(guān)golang http請求redirect內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- golang http請求封裝代碼
- Golang發(fā)送http GET請求的示例代碼
- golang使用http client發(fā)起get和post請求示例
- 詳解golang中發(fā)送http請求的幾種常見情況
- golang編程入門之http請求天氣實例
- golang高性能的http請求 fasthttp詳解