從HTTP GET和POST的區別說起

http://weblogs.asp.net/mschwarz/archive/2006/12/04/post-vs-get.aspx

http://www.yining.org/2010/05/04/http-get-vs-post-and-thoughts/

在推特上抱怨面試時問HTTP GETE和POST的區別得到回答都不滿意,有人不清楚,當時只回復了看 RFC2616。趁有空說說

面試時得到的回答大多是:POST是安全的,因爲被提交的數據看不到,或者被加密的,其它的還有GET的時候中文出現亂碼(在地址欄裏),數據最大長度限制等等。

說 POST 比 GET 安全肯定是錯的,POST跟GET都是明文傳輸,用httpfox等插件,或者像WireShark 等類似工具就能觀察到。

POST和GET的差別其實是很大的。語義上,GET是獲取指定URL上的資源,是讀操作,重要的一點是不論對某個資源GET多少次,它的狀態是不會改變的,在這個意義上,我們說GET是安全的(不是被密碼學或者數據保護意義上的安全)。因爲GET是安全的,所以GET返回的內容可以被瀏覽器,Cache服務器緩存起來(其中還有很多細節,但不影響這裏的討論)。

而POST的語意是對指定資源“追加/添加”數據,所以是不安全的,每次提交的POST,參與的代碼都會認爲這個操作會修改操作對象資源的狀態,於是,瀏覽器在你按下F5的時候會跳出確認框,緩存服務器不會緩存POST請求返回內容。

很遺憾到目前爲止沒有應聘者能夠提到這一點。我猜測這背後的原因大概有兩個,一是也許大多數人往往(我也一樣)滿足於只要完成任務就好,不管用哪個,表單提交了,數據處理了,內容顯示或者重新定向到另外一個頁面,就算完成了一個任務,從任務表裏劃掉,結束。而且對大部分項目(OA, CRM, MIS)的大部分情況下,用哪個似乎都可以。

同時,在被商業機構在媒體和書籍上宣傳兜售的WS-*概念和使用集成開發環境提供的“方便”的代碼生成工具後,“瞭解”到所有Web服務調用都是通過POST,更潛意識裏確定了POST和GET是一樣的,而且GET能做的,POST都能做,POST簡直就是GET++嘛。自然,能用POST就用POST,不必在乎兩者的差別了。

這又讓我想起最近學到的一個概念: Radius Of Comprehension,理解的半徑:

當學習概念A的時候,需要先了解概念B,而概念C又是理解B的前提。當B和C都是新的需要學習的概念時,可以說A的理解半徑是2,如圖:

A --> B --> C
|--1--|--2--|

在學習Web開發時,接觸到GET和POST時,“理解的半徑”可能包涵:

POST vs. GET
     |---> Conditional GET -> ETag -> Cache
     |         `--> Status Code
     `---> HTTP的方法 --> URL

往往因爲僅僅滿足於完成手上被要求的任務,或者懶於問一個爲什麼,我們就把自己的理解半徑設置成零,那麼就學不到更深入的東西,也因此僅僅知道POST和GET不同,而不再會了解不同在哪裏,什麼是Conditional GET和緩存header等概念。

從一個簡單的面試問題談到這,貌似小題大作了,寫到哪算哪吧。

<UPDATE>
看到Fenng Buzz 了這篇文字,引起一些評論,因此在這再討論兩個概念: 安全的(Safe)和冪等的(Idempotent)

安全的是指沒有明顯的對用戶有影響的副作用(包括修改該資源的狀態)。HTTP方法裏的GET和HEAD都是安全的。

冪等的是指一個方法不論多少次操作,結果都是一樣。PUT(把內容放到指定URL),DELETE(刪除某個URL代表的資源),雖然都修改了資源內容,但多次操作,結果是相同的,因此和HEAD,GET一樣都是冪等的。

所以根據HTTP協議,GET是安全的,也是冪等的,而POST既不是安全的,也不是冪等的。
</UPDATE>


發佈了89 篇原創文章 · 獲贊 10 · 訪問量 61萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章