Go 学习笔记(76)— Go 标准库 net/http 创建客户端(发送 GET、POST 请求)
1. Get 請(qǐng)求
1.1 使用 net/http 包的快捷方法 GET
package mainimport ("fmt""io/ioutil""net/http"
)func main() {resp, err := http.Get("http://www.baidu.com")if err != nil {fmt.Println(err)}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println(err)}fmt.Println(string(body))
}
1.2 自定義客戶端
package mainimport ("fmt""io/ioutil""net/http"
)func main() {client := &http.Client{}request, err := http.NewRequest("GET", "http://www.baidu.com", nil)if err != nil {fmt.Println(err)}resp, err := client.Do(request)if err != nil {fmt.Println(err)}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println(err)}fmt.Println(string(body))
}
使用自定義 HTTP 客戶端意味著可對(duì)請(qǐng)求設(shè)置報(bào)頭、基本身份驗(yàn)證和 cookies 。鑒于使用快捷方法和自定義HTTP 客戶端時(shí), 發(fā)出請(qǐng)求所需代碼的差別很小, 建議除非要完成的任務(wù)非常簡(jiǎn)單,否則都使用自定義HTTP 客戶端。
2. POST 請(qǐng)求
package mainimport ("fmt""io/ioutil""net/http""strings"
)func main() {data := strings.NewReader(`{"some": "json"}`)resp, err := http.Post("https://httpbin.org/post", "application/json", data)if err != nil {fmt.Println(err)}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println(err)}fmt.Println(string(body))
}
輸出結(jié)果:
{"args": {}, "data": "{\"some\": \"json\"}", "files": {}, "form": {}, "headers": {"Accept-Encoding": "gzip", "Content-Length": "16", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "Go-http-client/2.0", "X-Amzn-Trace-Id": "Root=1-60575025-22341e95217463712e18068e"}, "json": {"some": "json"}, "origin": "192.168.0.110", "url": "https://httpbin.org/post"
}
3. 調(diào)試 HTTP
net/http/httputil 也提供了能夠讓您輕松調(diào)試 HTTP 客戶端和服務(wù)器的方法。這個(gè)包中的方法DumpRequestOut 和 DumpResponse 能夠讓您查看請(qǐng)求和響應(yīng)。
可對(duì)前一個(gè)示例進(jìn)行改進(jìn),以使用 net/http/httputil 包中的 DumpRequestOut 和 DumpResponse
方法來(lái)支持日志功能。這些方法顯示請(qǐng)求和響應(yīng)的報(bào)頭,還有返回的響應(yīng)體。
package mainimport ("fmt""io/ioutil""net/http""net/http/httputil""strings"
)func main() {client := &http.Client{}data := strings.NewReader(`{"some": "json"}`)request, err := http.NewRequest("POST", "https://httpbin.org/post", data)request.Header.Add("Accept", "application/json") // 增加請(qǐng)求報(bào)文頭/*通過(guò)使用 Accept 報(bào)頭, 客戶端告訴服務(wù)器它想要的是 application/json,而服務(wù)器返回?cái)?shù)據(jù)時(shí)將 Content-Type 報(bào)頭設(shè)置成了application/json。*/if err != nil {fmt.Println(err)}debugReq, err := httputil.DumpRequestOut(request, true)if err != nil {fmt.Println(err)}fmt.Println("debugReq is ", string(debugReq))resp, err := client.Do(request)if err != nil {fmt.Println(err)}defer resp.Body.Close()debugResponse, err := httputil.DumpResponse(resp, true)if err != nil {fmt.Println(err)}fmt.Println("debugResponse is ", string(debugResponse))body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println(err)}fmt.Println(string(body))
}
輸出結(jié)果:
debugReq is POST /post HTTP/1.1
Host: httpbin.org
User-Agent: Go-http-client/1.1
Content-Length: 16
Accept: application/json
Accept-Encoding: gzip{"some": "json"}
debugResponse is HTTP/2.0 200 OK
Content-Length: 441
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Sun, 21 Mar 2021 14:35:01 GMT
Server: gunicorn/19.9.0
4. 處理超時(shí)
使用默認(rèn)的 HTTP 客戶端時(shí),沒(méi)有對(duì)請(qǐng)求設(shè)置超時(shí)時(shí)間。這意味著如果服務(wù)器沒(méi)有響應(yīng),則請(qǐng)求將無(wú)限期地等待或掛起。對(duì)于任何請(qǐng)求,都建議設(shè)置超時(shí)時(shí)間。這樣如果請(qǐng)求在指定的時(shí)間內(nèi)沒(méi)有完成, 將返回錯(cuò)誤。
client := &http.Client{Timeout: 1 * time.Second,}
上述配置要求客戶端在 1s 內(nèi)完成請(qǐng)求。但是因?yàn)榉?wù)器的響應(yīng)速度不夠快。完全有可能發(fā)生請(qǐng)求超時(shí)的情況。如下:
Post https://httpbin.org/post: net/http:request canceled (Client.Timeout exceeded while awaiting headers)
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x63491b]
總結(jié)
以上是生活随笔為你收集整理的Go 学习笔记(76)— Go 标准库 net/http 创建客户端(发送 GET、POST 请求)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2022-2028年中国石油钻井井下工具
- 下一篇: 2022-2028年中国玫瑰花行业市场研