Go HTTP GET 請求可以傳送 body 嗎
來源:腦子進煎魚了
大家好,我是煎魚。
前段時間遇到一個朋友,他跟我說他們在開發一個 Go 專案時,遇到了一個爭議點,說來也好理解。WEB UI 端選擇 GET、POST 型別時,程式是否要區分所傳遞的值(例如:Body),還是不管是什麼型別都傳。
一派認為無所謂,反正都能傳。又沒限制。
一派認為規範如此,不應該傳。應該針對 HTTP POST 型別,使用 POST 請求的 body 來傳遞引數。在 GET 請求裡使用 URI 來進行引數傳遞。
看著似乎都有各自的道理,僵持不下。
RFC7231 怎麼說
要看網際網路協議的相關標準,必然是 RFC 了。首先看看 RFC7231[1] 中的 4.3.1 小節是怎麼說的。
如下摘抄:
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
大概意思:在 GET 型別的請求裡使用 body 是一個沒有定義的語義。如果在 GET 請求的 body 裡傳遞引數可能會被某些實現方拒絕該請求。
也就是這個混著傳的行為並不符合 RFC 規範,至少官方是不推薦不鼓勵這樣的使用方式。但並沒有禁止這個行為。
記住這個結論。接下來我們進行測試。
程式支援程度
我們起一個 HTTP Sever 用於測試和驗證,看看在具體的程式語言的實現中是否可以支援。
如下 Go 程式碼:
func hello(w http.ResponseWriter, req *http.Request) {
b, _ := io.ReadAll(req.Body)
w.Write(b)
}
func main() {
http.HandleFunc("/hello_world", hello)
http.ListenAndServe(":7001", nil)
}
在命令列執行 CURL 進行測試:
$ curl -X GET localhost:7001/hello_world -d '煎魚'
煎魚
看來在 Go 裡面是可以的。
那既然 RFC 沒有禁止,Go 的測試也正常。看來就是隻是口頭上的 “不鼓勵” 和 “不推薦” 嗎?
那別的場景也都支援嗎?
實際上也不是,例如:XMLHttpRequest 規範[2] 中有明確提到:
如果請求方法為 GET 或 HEAD,body 引數會被忽略。
總結
在 GET 型別裡傳 body 引數,從 RFC7231 標準來定義。官方是不推薦、不鼓勵這麼去使用的。
但是呢,這是一個沒有明確禁止的事。
而從各個 HTTP 實現的客戶端來看,一開始還是有不少不支援的。但掰扯了好多年後,大多數都支援了。(畢竟使用者的訴求也是很重要的)
甚至印象最深的,ES 直接就在 GET 請求裡傳了 body:
對應的 CURL:
curl -X GET "localhost:9200/my-index-000001/_search?from=40&size=20&pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"term": {
"user.id": "kimchy"
}
}
}
'
但也有不支援的,例如在 Chrome 瀏覽器下測試 XMLHttpRequest、Fetch 對此都會忽略或出現報錯。
結論上來講,GET 請求能不能傳 body,這是一個 RFC 規範不鼓勵。但是實現方大部分都支援的一個情況。
企業和團隊內部的話,建議達成研發規範的共識即可。不過我個人而言,都會區分開。
參考資料
RFC7231:
[2]XMLHttpRequest 規範:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2997583/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- HTTP GET請求傳bodyHTTP
- Go使用net/http庫傳送GET請求GoHTTP
- java傳送http的get、post請求JavaHTTP
- Golang:使用go-resty/resty傳送http請求get和postGolangRESTHTTP
- 【轉】怎麼用PHP傳送HTTP請求(POST請求、GET請求)?PHPHTTP
- 傳送GET請求 示例
- 使用HttpClient傳送GET請求HTTPclient
- perl傳送http請求HTTP
- java傳送http請求JavaHTTP
- Go語言開發傳送Get和Post請求Go
- java傳送post請求 ,請求資料放到body裡Java
- Go語言HTTP請求流式寫入bodyGoHTTP
- java傳送GET和post請求Java
- PHP傳送POST和GET請求PHP
- 使用httpclient傳送http請求HTTPclient
- httprequest- post- get -傳送請求HTTP
- php 利用socket傳送GET,POST請求PHP
- java傳送get請求帶引數Java
- 使用Feign傳送HTTP請求HTTP
- python傳送HTTP POST請求PythonHTTP
- .net 後臺 傳送http請求HTTP
- SpringMVC中如何傳送GET請求、POST請求、PUT請求、DELETE請求。SpringMVCdelete
- 路由 any 不可以 get 請求嗎?路由
- go 自定義http.Client - 動態修改請求BodyGoHTTPclient
- Java用HttpClient3傳送http/https協議get/post請求,傳送map,jsoJavaHTTPclient協議JS
- postman(二):使用postman傳送get or post請求Postman
- file_get_contents傳送post請求
- Android 傳送HTTP GET POST 請求以及通過 MultipartEntityBuilder 上傳檔案(二)AndroidHTTPUI
- 使用requests庫來傳送HTTP請求HTTP
- nodejs使用request傳送http請求NodeJSHTTP
- cURL實現傳送Get和Post請求(PHP)PHP
- 043-socket程式設計傳送GET請求程式設計
- PHP 傳送 HTTP 請求的幾種方式PHPHTTP
- Windows Phone 8.1 傳送http 網路請求。WindowsHTTP
- php curl_multi批量傳送http請求PHPHTTP
- go http請求GoHTTP
- 如何在 Go 中傳送表單請求Go
- 理解ASP.NET Core - 傳送Http請求(HttpClient)ASP.NETHTTPclient