詳解golang開(kāi)發(fā)中http請(qǐng)求redirect的問(wèn)題
這兩天在開(kāi)發(fā)項(xiàng)目的時(shí)候遇到了一個(gè)問(wèn)題,請(qǐng)求了一個(gè)URL,它會(huì)302到另一個(gè)地址,本意上只是想檢查這個(gè)URL是否會(huì)做3XX的redirect跳轉(zhuǎn),結(jié)果每次reqeust都會(huì)返回最后一跳的結(jié)果。后來(lái)就看了下源碼,了解下請(qǐng)求跳轉(zhuǎn)的機(jī)制
實(shí)現(xiàn)代碼
看下實(shí)現(xiàn)的簡(jiǎ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)沒(méi)法實(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)求過(guò)的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,如果沒(méi)有設(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方法上面有一行說(shuō)明,
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開(kāi)發(fā)中http請(qǐng)求redirect的問(wèn)題的文章就介紹到這了,更多相關(guān)golang http請(qǐng)求redirect內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
手把手帶你走進(jìn)Go語(yǔ)言之語(yǔ)法基礎(chǔ)解析
這篇文章主要介紹了手把手帶你走進(jìn)Go語(yǔ)言之語(yǔ)法基礎(chǔ),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09Go語(yǔ)言設(shè)置JSON的默認(rèn)值操作
這篇文章主要介紹了Go語(yǔ)言設(shè)置JSON的默認(rèn)值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Golang切片連接成字符串的實(shí)現(xiàn)示例
本文主要介紹了Golang切片連接成字符串的實(shí)現(xiàn)示例,可以使用Go語(yǔ)言中的內(nèi)置函數(shù)"String()"可以將字節(jié)切片轉(zhuǎn)換為字符串,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11從淺入深帶你掌握Golang數(shù)據(jù)結(jié)構(gòu)map
在?Go?語(yǔ)言中,map?是一種非常常見(jiàn)的數(shù)據(jù)類型,它可以用于快速地檢索數(shù)據(jù)。本篇文章將介紹?Go?語(yǔ)言中的?map,包括?map?的定義、初始化、操作和優(yōu)化,需要的可以參考一下2023-04-04詳解Golang中string的實(shí)現(xiàn)原理與高效使用
在Go語(yǔ)言中,無(wú)論是字符串常量、字符串變量還是代碼中出現(xiàn)的字符串字面量,它們的類型都被統(tǒng)一設(shè)置為string,下面就跟隨小編一起來(lái)了解一下Golang中string的實(shí)現(xiàn)原理與高效使用吧2024-01-01基于微服務(wù)框架go-micro開(kāi)發(fā)gRPC應(yīng)用程序
這篇文章介紹了基于微服務(wù)框架go-micro開(kāi)發(fā)gRPC應(yīng)用程序的方法,文中通過(guò)示例代碼介紹的非常詳細(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是開(kāi)源免費(fèi)的,而且開(kāi)發(fā)支持vscode的插件相對(duì)比較容易,更新速度也很快,需要的朋友可以參考下2023-07-07Go語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的并發(fā)聊天室的項(xiàng)目實(shí)戰(zhàn)
本文主要介紹了Go語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的并發(fā)聊天室的項(xiàng)目實(shí)戰(zhàn),文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03