HTTP|GET 和 POST 區別?

HTTP|GET 和 POST 區別?

一、最普遍的答案

我們在Google或百度上搜索這個問題時,得到最多的答案就是如下三點,而這似乎也成為了“標準答案”,其實這個答案有待商榷。

1。 GET使用URL或Cookie傳參,而POST將資料放在BODY中。

2。 GET方式提交的資料有長度限制,則POST的資料則可以非常大。

3。 POST比GET安全,因為資料在位址列上不可見。

二、“標準答案”其實是錯的

1。 GET使用URL或Cookie傳參,而POST將資料放在BODY中

GET和POST是由HTTP協議定義的。在HTTP協議中,Method和Data(URL, Body, Header)是正交的兩個概念,也就是說,使用哪個Method與應用層的資料如何傳輸是沒有相互關係的。

HTTP沒有要求,如果Method是POST資料就要放在BODY中。也沒有要求,如果Method是GET,資料(引數)就一定要放在URL中而不能放在BODY中。

那麼,網上流傳甚廣的這個說法是從何而來的呢?我在HTML標準中,找到了相似的描述。這和網上流傳的說法一致。但是這只是HTML標準對HTTP協議的用法的約定。怎麼能當成GET和POST的區別呢?

而且,現代的Web Server都是支援GET中包含BODY這樣的請求。雖然這種請求不可能從瀏覽器發出,但是現在的Web Server又不是隻給瀏覽器用,已經完全地超出了HTML伺服器的範疇了。

2。 GET方式提交的資料有長度限制,則POST的資料則可以非常大

先說結論:HTTP協議對GET和POST都沒有對長度的限制。HTTP協議明確地指出了,HTTP頭和Body都沒有長度的要求。

首先是“GET方式提交的資料有長度限制”,如果我們使用GET透過URL提交資料,那麼GET可提交的資料量就跟URL的長度有直接關係了。而實際上,URL不存在引數上限的問題,HTTP協議規範沒有對URL長度進行限制。這個限制是特定的瀏覽器及伺服器對它的限制。IE對URL長度的限制是2083位元組(2K+35)。對於其他瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決於作業系統的支援。

注意這個限制是整個URL長度,而不僅僅是你的引數值資料長度。

POST也是一樣,POST是沒有大小限制的,HTTP協議規範也沒有對POST資料進行大小限制,起限制作用的是伺服器的處理程式的處理能力。

當然,我們常說GET的URL會有長度上的限制這個說法是怎麼回事呢?雖然這個不是GET和POST的本質區別,但是我們也可以說說導致URL長度限制的兩方面的原因:

1。 瀏覽器。早期的瀏覽器會對URL長度做限制。而現在的具體限制是怎麼樣的,我自己沒有親測過,就不復制網上的說法啦。

2。 伺服器。URL長了,對伺服器處理也是一種負擔。原本一個會話就沒有多少資料,現在如果有人惡意地構造幾個M大小的URL,並不停地訪問你的伺服器。伺服器的最大併發數顯然會下降。另一種攻擊方式是,告訴伺服器Content-Length是一個很大的數,然後只給伺服器發一點兒資料,伺服器你就傻等著去吧。哪怕你有超時設定,這種故意的次次訪問超時也能讓伺服器吃不了兜著走。有鑑於此,多數伺服器出於安全啦、穩定啦方面的考慮,會給URL長度加限制。但是這個限制是針對所有HTTP請求的,與GET、POST沒有關係。

3。 POST比GET安全,因為資料在位址列上不可見

這個說法其實也是基於上面的1,2兩點的基礎上來說的,我覺得沒什麼問題,但是需要明白為什麼使用GET在位址列上就不安全了,以及還有沒有其他原因說明“POST比GET安全”。

透過GET提交資料,使用者名稱和密碼將明文出現在URL上,因為登入頁面有可能被瀏覽器快取,其他人檢視瀏覽器的歷史紀錄,那麼別人就可以拿到你的賬號和密碼了,除此之外,使用GET提交資料還可能會造成Cross-site request forgery攻擊。

三、我的理解

“1。 GET使用URL或Cookie傳參,而POST將資料放在BODY中”,這個是因為HTTP協議用法的約定。並非它們的本身區別。

“2。 GET方式提交的資料有長度限制,則POST的資料則可以非常大”,這個是因為它們使用的作業系統和瀏覽器設定的不同引起的區別。也不是GET和POST本身的區別。

“3。 POST比GET安全,因為資料在位址列上不可見”,這個說法沒毛病,但依然不是GET和POST本身的區別。

雖然這三點不是它們的本身區別,但至少是它們在使用上的區別,所以我在面試這個問題時,如果面試者能夠回答上面三點我基本會給個及格分。那麼你想不想要更高的分數?

四、終極區別

GET和POST最大的區別主要是GET請求是冪等性的,POST請求不是。這個是它們本質區別,上面的只是在使用上的區別。

什麼是冪等性?冪等性是指一次和多次請求某一個資源應該具有同樣的副作用。簡單來說意味著對同一URL的多個請求應該返回同樣的結果。

關於冪等性看我評論上推薦的一篇文章。

正因為它們有這樣的區別,所以不應該且不能用get請求做資料的增刪改這些有副作用的操作。因為get請求是冪等的,在網路不好的隧道中會嘗試重試。如果用get請求增資料,會有重複操作的風險,而這種重複操作可能會導致副作用(瀏覽器和作業系統並不知道你會用get請求去做增操作)。