http GET 和 POST 請求的優(yōu)缺點、區(qū)別以及誤區(qū)

Get和Post在面試中一般都會問到,一般的區(qū)別:

(1)post更安全(不會作為url的一部分,不會被緩存、保存在服務器日志、以及瀏覽器瀏覽記錄中)
(2)post發(fā)送的數(shù)據(jù)更大(get有url長度限制)
(3)post能發(fā)送更多的數(shù)據(jù)類型(get只能發(fā)送ASCII字符)
(4)post比get慢
(5)post用于修改和寫入數(shù)據(jù),get一般用于搜索排序和篩選之類的操作(淘寶,支付寶的搜索查詢都是get提交),目的是資源的獲取,讀取數(shù)據(jù)
雖然在開發(fā)中經(jīng)常用get或者post請求,但是由于我們資歷經(jīng)驗的欠缺,或許就重來沒有深究過什么場合用get請求,什么場合用post請求,我相信不止我一個人當看到第4,5條的時候,就會明白為什么面試官對我們的回答不滿意,也明白了自己對get或post用法理解的欠缺,那么get比post更快,究竟快多少呢?表現(xiàn)在那些方面?

一、為什么get比post更快

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

2.最重要的一條,post在真正接收數(shù)據(jù)之前會先將請求頭發(fā)送給服務器進行確認,然后才真正發(fā)送數(shù)據(jù)
post請求的過程:
(1)瀏覽器請求tcp連接(第一次握手)
(2)服務器答應進行tcp連接(第二次握手)
(3)瀏覽器確認,并發(fā)送post請求頭(第三次握手,這個報文比較小,所以http會在此時進行第一次數(shù)據(jù)發(fā)送)
(4)服務器返回100 Continue響應
(5)瀏覽器發(fā)送數(shù)據(jù)
(6)服務器返回200 OK響應
get請求的過程:
(1)瀏覽器請求tcp連接(第一次握手)
(2)服務器答應進行tcp連接(第二次握手)
(3)瀏覽器確認,并發(fā)送get請求頭和數(shù)據(jù)(第三次握手,這個報文比較小,所以http會在此時進行第一次數(shù)據(jù)發(fā)送)
(4)服務器返回200 OK響應
也就是說,目測get的總耗是post的2/3左右,這個口說無憑,網(wǎng)上已經(jīng)有網(wǎng)友進行過測試。

3.get會將數(shù)據(jù)緩存起來,而post不會
可以做個簡短的測試,使用ajax采用get方式請求靜態(tài)數(shù)據(jù)(比如html頁面,圖片)的時候,如果兩次傳輸?shù)臄?shù)據(jù)相同,第二次以后消耗的時間將會在10ms以內(nèi)(chrome測試),而post每次消耗的時間都差不多。經(jīng)測試,chrome和firefox下如果檢測到get請求的是靜態(tài)資源,則會緩存,如果是數(shù)據(jù),則不會緩存,但是IE什么都會緩存起來,當然,應該沒有人用post去獲取靜態(tài)數(shù)據(jù)吧,反正我是沒見過。

4.post不能進行管道化傳輸
http權威指南中是這樣說的:http的一次會話需要先建立tcp連接(大部分是tcp,但是其他安全協(xié)議也是可以的),然后才能通信,如果 每次連接都只進行一次http會話,那這個連接過程占的比例太大了!于是出現(xiàn)了持久連接:在http/1.0+中是connection首部中添加keep-alive值,在http/1.1中是在connection首部中添加persistent值,當然兩者不僅僅是命名上的差別,http/1.1中,持久連接是默認的,除非顯示在connection中添加close,否則持久連接不會關閉,而http/1.0+中則恰好相反,除非顯示在connection首部中添加keep-alive,否則在接收數(shù)據(jù)包后連接就斷開了。
出現(xiàn)了持久連接還不夠,在http/1.1中,還有一種稱為管道通信的方式進行速度優(yōu)化:把需要發(fā)送到服務器上的所有請求放到輸出隊列中,在第一個請求發(fā)送出去后,不等到收到服務器的應答,第二個請求緊接著就發(fā)送出去,但是這樣的方式有一個問題:不安全,如果一個管道中有10個連接,在發(fā)送出9個后,突然服務器告訴你,連接關閉了,此時客戶端即使收到了前9個請求的答復,也會將這9個請求的內(nèi)容清空,也就是說,白忙活了……此時,客戶端的這9個請求需要重新發(fā)送。這對于冪等請求還好(比如get,多發(fā)送幾次都沒關系,每次都是相同的結(jié)果),如果是post這樣的非冪等請求(比如支付的時候,多發(fā)送幾次就慘了),肯定是行不通的。
所以,post請求不能通過管道的方式進行通信!很有可能,post請求需要重新建立連接,這個過程不跟完全沒優(yōu)化的時候一樣了么?所以,在可以使用get請求通信的時候,不要使用post請求,這樣用戶體驗會更好,當然,如果有安全性要求的話,post會更好。管道化傳輸在瀏覽器端的實現(xiàn)還需考證,貌似默認情況下大部分瀏覽器(除了opera)是不進行管道化傳輸?shù)?,除非手動開啟!

二、get傳參最大長度的理解誤區(qū)

1.總結(jié)
(1)http協(xié)議并未規(guī)定get和post的長度限制
(2)get的最大長度限制是因為瀏覽器和web服務器限制了URL的長度
(3)不同的瀏覽器和web服務器,限制的最大長度不一樣
(4)要支持IE,則最大長度為2083byte,若支持Chrome,則最大長度8182byte

2.誤解
(1)首先即使get有長度限制,也是限制的整個URL的長度,而不僅僅是參數(shù)值數(shù)據(jù)長度,http協(xié)議從未規(guī)定get/post的請求長度限制是多少
(2)所謂的請求長度限制是由瀏覽器和web服務器決定和設置的,各種瀏覽器和web服務器的設定均不一樣,這依賴于各個瀏覽器廠家的規(guī)定或者可以根據(jù)web服務器的處理能力來設定。IE 和 Safari 瀏覽器 限制 2k,Opera 限制4k,F(xiàn)irefox 限制 8k(非常老的版本 256byte),如果超出了最大長度,大部分的服務器直接截斷,也有一些服務器會報414錯誤。

3.各個瀏覽器和web服務器的最大長度總結(jié)
瀏覽器
(1)IE:IE瀏覽器(Microsoft Internet Explorer) 對url長度限制是2083(2K+53),超過這個限制,則自動截斷(若是form提交則提交按鈕不起作用)。
(2)firefox:firefox(火狐瀏覽器)的url長度限制為 65536字符,但實際上有效的URL最大長度不少于100,000個字符。
(3)chrome:chrome(谷歌)的url長度限制超過8182個字符返回本文開頭時列出的錯誤。
(4)Safari:Safari的url長度限制至少為 80 000 字符。
(5)Opera:Opera 瀏覽器的url長度限制為190 000 字符。Opera9 地址欄中輸入190000字符時依然能正常編輯。
服務器
(1)Apache:Apache能接受url長度限制為8 192 字符
(2)IIS:Microsoft Internet Information Server(IIS)能接受url長度限制為16384個字符。這個是可以通過修改的
(IIS7)
configuration/system.webServer/security/requestFiltering/requestLimits@maxQueryStringsetting.

該文章轉(zhuǎn)載于CSDN博客園 鏈接

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容