GET 和 POST 的區別 以及爲何 GET請求 比 POST請求 更快

引子: 和朋友的聊天中得知他公司後臺接口所有都是 POST 請求, 我表示很納悶爲何全是 POST 請求呢?html

GET 比 POST 安全,或者說 便於後臺方便,後臺不用區分包裝類  (因此所有用 POST 請求)?web

相對來講是POST更安全些,可是後臺全部接口都是帶敏感性的麼? 好比靜態數據(數據字典、省市區、類型之類的)這時候也要 post ?ajax

帶敏感性的請求POST徹底是應該的,但普通請求(大多數獲取數據請求)都應該往GET請求看齊,由於GET請求對於瀏覽器來講減輕了其壓力、並且請求比POST快,提高頁面數據響應、渲染速度;chrome

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

區別:

分類 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

相關文章
相關標籤/搜索