詳解golang開發(fā)中http請(qǐng)求redirect的問題
這兩天在開發(fā)項(xiàng)目的時(shí)候遇到了一個(gè)問題,請(qǐng)求了一個(gè)URL,它會(huì)302到另一個(gè)地址,本意上只是想檢查這個(gè)URL是否會(huì)做3XX的redirect跳轉(zhuǎn),結(jié)果每次reqeust都會(huì)返回最后一跳的結(jié)果。后來就看了下源碼,了解下請(qǐng)求跳轉(zhuǎn)的機(jī)制
實(shí)現(xiàn)代碼
看下實(shí)現(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會(huì)302跳轉(zhuǎn)到https://www.qq.com。我們使用curl可以看到使用302的跳轉(zhuǎn)。
可是我只想獲取第一跳的的response 的狀態(tài)碼。發(fā)現(xiàn)沒法實(shí)現(xiàn)了,所以看了下源碼。
http請(qǐng)求為什么可以做到多次redirect
看了下 client.Do 源碼實(shí)現(xiàn)
607 err = c.checkRedirect(req, reqs)
代碼的上下文,可以看出 req是將要請(qǐng)求的request,reqs已經(jīng)請(qǐ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)就拋出錯(cuò)誤結(jié)束這次請(qǐng)求了。
大體上流程已經(jīng)搞明白。只要設(shè)置checkRedirect返回error,理論上就能實(shí)現(xiàn)只請(qǐ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 fmt.Errorf("first response") } response, _ := client.Do(reqest) fmt.Println(response.StatusCode) } /private/var/folders/4h/lrsc4fyd12v9ctl31ggk5ckc0000gp/T/___go_build_main_go #gosetup 302
基本實(shí)現(xiàn)了。
其實(shí),在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ā)送下一個(gè)請(qǐng)求,并且返回最近的響應(yīng)且其主體未關(guān)閉。
可以看到返回 ErrUseLastResponse是官方的建議的設(shè)置
最終的代碼實(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請(qǐng)求redirect的問題的文章就介紹到這了,更多相關(guān)golang http請(qǐng)求redirect內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang切片連接成字符串的實(shí)現(xiàn)示例
本文主要介紹了Golang切片連接成字符串的實(shí)現(xiàn)示例,可以使用Go語言中的內(nèi)置函數(shù)"String()"可以將字節(jié)切片轉(zhuǎn)換為字符串,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11從淺入深帶你掌握Golang數(shù)據(jù)結(jié)構(gòu)map
在?Go?語言中,map?是一種非常常見的數(shù)據(jù)類型,它可以用于快速地檢索數(shù)據(jù)。本篇文章將介紹?Go?語言中的?map,包括?map?的定義、初始化、操作和優(yōu)化,需要的可以參考一下2023-04-04詳解Golang中string的實(shí)現(xiàn)原理與高效使用
在Go語言中,無論是字符串常量、字符串變量還是代碼中出現(xiàn)的字符串字面量,它們的類型都被統(tǒng)一設(shè)置為string,下面就跟隨小編一起來了解一下Golang中string的實(shí)現(xiàn)原理與高效使用吧2024-01-01基于微服務(wù)框架go-micro開發(fā)gRPC應(yīng)用程序
這篇文章介紹了基于微服務(wù)框架go-micro開發(fā)gRPC應(yīng)用程序的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07初學(xué)Go必備的vscode插件及最常用快捷鍵和代碼自動(dòng)補(bǔ)全
這篇文章主要給大家介紹了關(guān)于初學(xué)vscode寫Go必備的vscode插件及最常用快捷鍵和代碼自動(dòng)補(bǔ)全的相關(guān)資料,由于vscode是開源免費(fèi)的,而且開發(fā)支持vscode的插件相對(duì)比較容易,更新速度也很快,需要的朋友可以參考下2023-07-07Go語言實(shí)現(xiàn)一個(gè)簡單的并發(fā)聊天室的項(xiàng)目實(shí)戰(zhàn)
本文主要介紹了Go語言實(shí)現(xiàn)一個(gè)簡單的并發(fā)聊天室的項(xiàng)目實(shí)戰(zhàn),文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03