GET 和 POST 的區別 以及為什么 GET請求 比 POST請求 更快


引子: 和朋友的聊天中得知他公司后台接口全部都是 POST 請求, 我表示很納悶為什么全是 POST 請求呢?

GET 比 POST 安全,或者說 便於后台方便,后台不用區分包裝類  (所以全部用 POST 請求)?

相對來說是POST更安全些,但是后台所有接口都是帶敏感性的么? 比如靜態數據(數據字典、省市區、類型之類的)這時候也要 post ?

帶敏感性的請求POST完全是應該的,但普通請求(大多數獲取數據請求)都應該往GET請求看齊,因為GET請求對於瀏覽器來說減輕了其壓力、而且請求比POST快,提升頁面數據響應、渲染速度;

先看看他們區別再看從哪些方面說明為什么GET更快?還有快多少呢:

區別:

分類 GET POST 對比
后退按鈕/刷新 無害 數據會被重新提交(瀏覽器應該告知用戶數據會被重新提交)。 每次都重新提交這無疑會對瀏覽器造成壓力,該問題也是作為web端性能優化的重要方向之一
緩存 能被緩存 不能緩存 緩存可以為瀏覽器減少請求鏈數,web端性能優化的重要方向之一
歷史 參數保留在瀏覽器歷史中。 參數不會保存在瀏覽器歷史中。 相當於緩存,可減少瀏覽器壓力
對數據長度的限制 是的。當發送數據時,GET 方法向 URL 添加數據;URL 的長度是受限制的(URL 的最大長度是 2048 個字符)。 無限制。

HTTP 協議沒有 Body 和 URL 的長度限制,對 URL 限制的大多是瀏覽器和服務器的原因。

服務器是因為處理長 URL 要消耗比較多的資源,為了性能和安全(防止惡意構造長 URL 來攻擊)考慮,會給 URL 長度加限制

安全性 與 POST 相比,GET 的安全性較差,因為所發送的數據是 URL 的一部分。在發送密碼或其他敏感信息時絕不要使用 GET ! POST 比 GET 更安全,因為參數不會被保存在瀏覽器歷史或 web 服務器日志中。

從傳輸的角度來說,他們都是不安全的,因為 HTTP 在網絡上是明文傳輸的,瀏覽器F12下什么都一目了然,或者抓個包,就能完整地獲取數據報文。

要想安全傳輸,Encode(轉碼)當然對於懂的人來說也不安全; 比較安全的只有加密,也就是 HTTPS

對數據類型的限制 只允許 ASCII 字符。 沒有限制。也允許二進制數據。

POST選擇更多

 快的原因:

1.post請求包含更多的請求頭

  因為post需要在請求的body部分包含數據,所以會多了幾個數據描述部分的首部字段(如content-type),這其實是微乎其微的

2.最重要的一條,post在真正接受數據之前會先將請求頭發送給服務器進行確認,然后才真正發送數據

  post請求的過程:

  1.瀏覽器請求tcp連接(第一次握手)

  2.服務器答應進行tcp連接(第二次握手)

  3.瀏覽器確認,並發送post請求頭(第三次握手,這個報文比較小,所以http會在此時進行第一次數據發送)

  4.服務器返回100 continue響應

  5.瀏覽器開始發送數據

  6.服務器返回200 ok響應

 

  get請求的過程

    1.瀏覽器請求tcp連接(第一次握手)

  2.服務器答應進行tcp連接(第二次握手)

  3.瀏覽器確認,並發送get請求頭和數據(第三次握手,這個報文比較小,所以http會在此時進行第一次數據發送)

  4.服務器返回200 ok響應

 

  也就是說,目測get的總耗是post的2/3左右

3.get會將數據緩存起來,而post不會

  可以做個簡短的測試,使用ajax采用get方式請求靜態數據(比如html頁面,圖片)的時候,如果兩次傳輸的數據相同,第二次以后耗費的時間將在10ms以內(chrome測試),而post每次耗費的時間都差不多……

  經測試,chrome下和firefox下如果檢測到get請求的是靜態資源,則會緩存,如果是數據,則不緩存,但是IE這個傻X啥都會緩存起來

  當然,應該沒人會用post去獲取靜態數據吧,反正我是沒看到過。

4.post不能進行管道化傳輸

  http權威指南中是這樣說的:

  http在的一次會話需要先建立tcp連接(大部分是tcp,但是其他安全協議也是可以的),然后才能通信,如果每次連接都只進行一次http會話,那這個連接過程占的比例太大了!

  於是出現了持久連接:在http/1.0+中是connection首部中添加keep-alive值,在http/1.1中是在connection首部中添加persistent值,當然兩者不僅僅是命名上的差別,http/1.1中,持久連接是默認的,除非顯示在connection中添加close,否則持久連接不會關閉,而http/1.0+中則恰好相反,除非顯示在connection首部中添加keep-alive,否則在接收數據包后連接就斷開了。

  出現了持久連接還不夠,在http/1.1中,還有一種稱為管道通信的方式進行速度優化:把需要發送到服務器上的所有請求放到輸出隊列中,在第一個請求發送出去后,不等到收到服務器的應答,第二個請求緊接着就發送出去,但是這樣的方式有一個問題:不安全,如果一個管道中有10個連接,在發送出9個后,突然服務器告訴你,連接關閉了,此時客戶端即使收到了前9個請求的答復,也會將這9個請求的內容清空,也就是說,白忙活了……此時,客戶端的這9個請求需要重新發送。這對於冪等請求還好(比如get,多發送幾次都沒關系,每次都是相同的結果),如果是post這樣的非冪等請求(比如支付的時候,多發送幾次就慘了),肯定是行不通的。

  所以,post請求不能通過管道的方式進行通信!

  很有可能,post請求需要重新建立連接,這個過程不跟完全沒優化的時候一樣了么?

  所以,在可以使用get請求通信的時候,不要使用post請求,這樣用戶體驗會更好,當然,如果有安全性要求的話,post會更好。

結語: 有不對之處歡迎指正

參考:

1. https://segmentfault.com/a/1190000018129846

2. https://www.cnblogs.com/strayling/p/3580048.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM