引言
get和post在面試過程中一般都會問到,一般的差別:
1.post更安全(不會作為url的一部分,不會被緩存、儲存在伺服器日志、以及浏覽器浏覽記錄中)
2.post發送的資料量更大(get有url長度限制)
3.post能發送更多的資料類型(get隻能發送ASCII字元)
4.post比get慢
我相信不止一個人跟我一樣有這種疑惑,既然post有這麼多優點,那我們為什麼要使用get?甚至有個同僚說,咱們封裝一個ajax底層,直接不用get算了……
但是,get比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連接配接(第一次握手)
3.浏覽器确認,并發送get請求頭和資料(第三次握手,這個封包比較小,是以http會在此時進行第一次資料發送)
4.伺服器傳回200 ok響應
也就是說,目測get的總耗是post的2/3左右
口說無憑,已經有網友進行測試了
尋根究底:Ajax請求的GET與POST方式比較
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會更好。
管道化傳輸在浏覽器端的實作還需考證,貌似預設情況下大部分浏覽器(除了opera)是不進行管道化傳輸的,除非手動開啟!!
:
