GET与POST
估計大家的標準答案是以下這些:
并不是說標準答案有誤,上述區別在大部分瀏覽器上是存在的,因為這些瀏覽器實現了 HTTP 標準。
然而從標準上看:從標準上來看,GET 和 POST 的區別如下:
- GET 用于獲取信息,是無副作用的,是冪等的,且可緩存
- POST 用于修改服務器上的數據,有副作用,非冪等(所以谷歌有那個經典的提示如下),不可緩存
但是將HTTP POST作為接口的形式使用時(AJAX技術等,當成一種RPC協議使用),就沒有這種彈框了。于是把一個POST請求實現為冪等就有實際的意義。POST冪等能讓很多業務的前后端交互更順暢,以及避免一些因為前端bug,觸控失誤等帶來的重復提交。將一個有副作用的操作實現為冪等必須得從業務上能定義出怎么就算是“重復”。這樣萬一用戶強行重復提交,服務器端可以做一次防護。
一、GET 和 POST 報文上的區別
GET 和 POST 方法沒有實質區別,只是報文格式不同。
GET 和 POST 只是 HTTP 協議中兩種請求方式,而 HTTP 協議是基于 TCP/IP 的應用層協議,無論 GET 還是 POST,用的都是同一個傳輸層協議,所以在傳輸上,沒有區別。
報文格式上:
不帶參數時,最大區別就是第一行方法名不同。
- POST 方法請求報文第一行是這樣的 POST /uri HTTP/1.1 \r\n
- GET 方法請求報文第一行是這樣的 GET /uri HTTP/1.1 \r
帶參數時報文的區別如下: - GET 方法的參數應該放在 url 中
- POST 方法參數應該放在 body 中
舉個例子,如果參數是 name=a, age=22
//GET簡約版報文: GET /index.php?name=a&age=22 HTTP/1.1 Host: localhost//POST簡約版報文: POST /index.php HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded name=a&age=22兩種方法本質上是 TCP 連接,沒有差別,也就是說,如果我不按規范來也是可以的。我們可以在 URL 上寫參數,然后方法使用 POST;也可以在 Body 寫參數,然后方法使用 GET。當然,這需要服務端支持。所以,當我們在AJAX等技術中使用POST/GET時,就沒有瀏覽器中那么多限制了,只要是符合HTTP格式的就可以發。所以我們可以自定義了,并沒有什么限制說GET一定不能沒有body,POST就一定不能把參放到<URL>的querystring上。因此其實可以更加自由的去利用格式。比如Elastic Search的_search api就用了帶body的GET。但是太自由也帶來了另一種麻煩,開發人員不得不每次討論確定參數是放url的path里,querystring里,body里,header里這種問題,太低效了。于是就有了一些列接口規范/風格。其中名氣最大的當屬REST。REST充分運用GET、POST、PUT和DELETE,約定了這4個接口分別獲取、創建、替換和刪除“資源”,REST最佳實踐還推薦在請求體使用json格式。這樣僅僅通過看HTTP的method就可以明白接口是什么意思,并且解析格式也得到了統一。
二、POST 方法比 GET 方法安全嗎
一句話帶過 ,從傳輸的角度來說,他們都是不安全的,因為 HTTP 在網絡上是明文傳輸的,只要在網絡節點上捉包,就能完整地獲取數據報文。要想安全傳輸,就只有加密,也就是 HTTPS。
三、GET方法的有長度限制
HTTP 協議沒有 Body 和 URL 的長度限制,對 URL 限制的大多是瀏覽器和服務器的原因。服務器是因為處理長 URL 要消耗比較多的資源,為了性能和安全(防止惡意構造長 URL 來攻擊)考慮,會給 URL 長度加限制。url 長度限制是某些瀏覽器和服務器的限制,和 HTTP 協議沒有關系。
四、POST 方法會產生兩個 TCP 數據包?
有些文章為了標新立異,強行講post 會將 header 和 body 分開發送,先發送 header,服務端返回 100 狀態碼再發送 body。其實,HTTP 協議中沒有明確說明 POST 會產生兩個 TCP 數據包,而且實際測試(Chrome)發現,header 和 body 不會分開發送。所以,header 和 body 分開發送是部分瀏覽器或框架的請求方法,不屬于 post 必然行為。
本文有抄作業
本文有抄作業
總結
- 上一篇: java自定义注解解析及自定义注解
- 下一篇: 新版微信又来了