傳統的 web 應用約定 http.GET 請求不容許攜帶請求體。然而如今已經是 9102 年,restful style的接口逐漸流行,一般咱們在查詢某個資源的時候會使用 http.GET 做爲請求方法,使用 json 格式的請求體做爲查詢條件 (舉個例子,elasticsearch 的查詢接口就是 http.GET,並把查詢條件放在請求體裏面)java
Golang 有原生的 httpclient (java 11 終於也有原生的 httpclient 了),經過如下代碼能夠獲得:web
import "net/http" func main() { client := &http.Client{} }
咱們來看看 http.Client 上都有些什麼經常使用方法:json
從 Get 方法的簽名看出,http.Get 不能附帶請求體,看來 Golang 的 httpclient 也沒有摒棄老舊的思想呢。別急,接着往下看restful
深刻到 Post 方法內部,有如下源碼app
func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error) { req, err := NewRequest("POST", url, body) if err != nil { return nil, err } req.Header.Set("Content-Type", contentType) return c.Do(req) }
不難看出,Post 方法內部是先使用 NewRequest()
構造出 http 請求,而後使用client.Do(request)
來執行 http 請求,那麼咱們是否能使用 NewRequest()
構造出帶有請求體的 http.GET 請求? 依照源碼,我給出如下代碼:elasticsearch
client := &http.Client{} //構造http請求,設置GET方法和請求體 request, _ := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/test", bytes.NewReader(requestBodyBytes)) //設置Content-Type request.Header.Set("Content-Type", "application/json") //發送請求,獲取響應 response, err := client.Do(request) defer response.Body.Close() //取出響應體(字節流),轉成字符串打印到控制檯 responseBodyBytes, err := ioutil.ReadAll(response.Body) fmt.Println("response:", string(responseBodyBytes))
實踐結果也是正確的,使用 NewRequest()
確實能夠構造附帶請求體的 http.GET 請求 (Golang 並無拒絕這樣的構造),只是 net/http 並無對外暴露相應的 Get 方法url