GET 和 POST 其實並沒有本質區別

報文

常見 GET 的報文如下

GET /index.html?name=everlose&age=28 HTTP/1.1
Host: localhost
...省略其他 request header

常見 POST 報文如下

POST /index.html HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
...省略其他 request header

name=everlose&age=28

從報文中可得知兩者的形式,區別也只在於 HTTP method。大家不要被常見形式誤解了,兩種請求方法都可以在路徑哪裏寫上 ? 後的參數,並且兩種方法都可以寫上 HTTP Body。

換言之,GET 和 POST 方法沒有實質區別,只是瀏覽器或者說其他的端對這兩者的表現給出了一些區別。

瀏覽器的表現形式

摘錄自 w3school HTTP 方法:GET 對比 POST

特性 GET POST
後退按鈕/刷新 無害 數據會被重新提交(瀏覽器應該告知用戶數據會被重新提交)。
書籤 可收藏爲書籤 不可收藏爲書籤
緩存 能被緩存 不能緩存
編碼類型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。爲二進制數據使用多重編碼。
歷史 參數保留在瀏覽器歷史中。 參數不會保存在瀏覽器歷史中。
對數據長度的限制 是的。當發送數據時,GET 方法向 URL 添加數據;URL 的長度是受限制的(URL 的最大長度是 2048 個字符)。 無限制。
對數據類型的限制 只允許 ASCII 字符。 沒有限制。也允許二進制數據。
安全性 與 POST 相比,GET 的安全性較差,因爲所發送的數據是 URL 的一部分。在發送密碼或其他敏感信息時絕不要使用 GET ! POST 比 GET 更安全,因爲參數不會被保存在瀏覽器歷史或 web 服務器日誌中。
可見性 數據在 URL 中對所有人都是可見的。 數據不會顯示在 URL 中。

總之瀏覽器遵照 HTTP 標準規定,給兩種方法加以區別:

  • GET 用於獲取信息,是無副作用的,是冪等的,且可緩存
  • POST 用於修改服務器上的數據,有副作用,非冪等,不可緩存

那麼最本質的區別是什麼

有文章 99%的人都理解錯了HTTP中GET與POST的區別 提到是

GET產生一個TCP數據包;POST產生兩個TCP數據包。

並且說所有瀏覽器都會在 POST 中發送兩次包,Firefox就只發送一次。

那麼本人在真實 wireshark 抓包得到的 chrome 瀏覽器,它的確 POST 只發了一個包

查閱文章http post請求發兩個tcp包後續得知在 ruby 做客戶端發起 POST 請求時,會發送兩個數據包。故而說:

大多數框架都是儘量在一個 TCP 包裏面把 HTTP 請求發出去的,但是也確實存在先發 HTTP 頭,然後發 Body 的框架。但是具體發多少個 TCP 包,這個是代碼的問題,是 TCP 協議棧的問題,跟 HTTP 沒關係。

回答問題,最本質的區別,仍舊沒有。

說到這裏大概大家會有個疑惑,似乎明明能看到發 POST 請求,跨域的時候能在控制檯看到兩個請求,第一個是 Options,但這其實是另一個話題,參見我的另外一篇 HTTP Options 跨域時發送兩個請求是怎麼回事?

參考

Fundebug-都 2019 年了,還問 GET 和 POST 的區別

WebTechGarden-99%的人都理解錯了HTTP中GET與POST的區別

john-zeng,http post請求發兩個tcp包後續

wiki-超文本傳輸協議

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章