標籤:winform style class blog java http
HTTP 基本概念
HTTP Request Methods
GET、POST 專業名稱是 HTTP Request Methods。但 HTTP Request Methods 不只是 GET 和 POST,完整列表如下:
- GET
- POST
- PUT
- DELETE
- HEAD
- OPTIONS
- TRACE
- CONNECT
- PATCH
REST 使用前四個:GET、POST、PUT、DELETE。因些這四個也是經常被一塊提及的,將這四個作為關鍵字進行搜尋,你會得到更深入的結果。
在一般的 Web 開發中,GET 和 POST 用得最多。
Safe Methods(安全方法)
RFC 2616 中定義如下(後面有翻譯):
Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.
Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.
網址:http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
維基百科中的說明(對 RFC 2616翻譯):
開發人員應當意識到他們的軟體代表了使用者在網際網路上進行互動,並且應當告知使用者,他們進行中的操作可能對他們自身或者其他人有未曾預料的重要影響。
特別地,對於GET和HEAD方法而言,除了進行擷取資源資訊外,這些請求不應當再有任何其他意義。也就是說,這些方法應當被認為是“安全的”。用戶端應當使用其他“非安全”方法,例如POST,PUT及DELETE來以特殊的方式(通常是按鈕而不是超連結)使得客戶能夠意識到可能要負的責任(例如一個按鈕帶來的資金交易)或者被告知正在請求的操作可能是不安全的(例如某個檔案將被上傳或刪除)。
但是,不能想當然地認為伺服器在處理某個GET請求時不會產生任何副作用。事實上,很多動態資源會把這作為其特性。這裡重要的區別在於使用者並沒有請求這一副作用,因此不應由使用者為這些副作用承擔責任。
拓撲圖
GET 與 POST 的區別
綜上所述,可總結如下:
- GET 僅用來擷取查看資訊,不能改變伺服器資訊。
- POST 用來改變伺服器資訊。
這裡說的改變,包括增加、修改和刪除。
這是 HTTP 協議中的要求,眾多瀏覽器和瀏覽器外掛程式都遵守這些約定。如果你的代碼不按照這約定來,可能會出現嚴重的後果。
使用 GET 改變伺服器資訊的嚴重後果
假定你編寫的 Web 程式或網站允許 GET 提交的修改,比如允許使用者通過以下 Url 直接刪除編寫為 1024 的訂單:
~/orders/delete/1024
那麼在訂單的管理(或列表)頁面,你可能會定義一個刪除串連如下:
<a href="/orders/delete/1024">刪除</a>
當然不會這麼簡單,一般都會在刪除之前會提示使用者一下,加上確認提示指令碼:
<a href="/orders/delete/1024" onclick="return confirm(‘確實要刪除嗎?‘)">刪除</a>
(說明:我在這裡只是示簡單例下,添加確認刪除還是建議使用 Unobtrusive JavaScript 方式,可以使用 jQuery。)
很多開發人員以為這樣就萬事大吉了,有了確認提示,也不怕誤刪。但問題就恰恰出在這裡,2005年時,Google發布了一款瀏覽器加速外掛程式:Google Web Accelerator(以下簡稱 GWA),讓這種問題嚴重的暴露了出來。
GWA 通過多種技術來加速,其中一種就是頁面積極式載入:比如你在查看我這篇文章的時候,GWA 可能把我前一篇或其它文章預先在後台下載,這樣你在點擊時,就節省了時間,起到了加速的效果。
GWA 的積極式載入是根據當前頁面中的連結來的,根據 HTTP 的協議,點選連結時使用 GET 方法擷取資訊,因些不會對伺服器造成影響。因此 GWA 會放心的載入當前頁面連結對應的網頁。當然也可能會加速上面提到的訂單刪除連結,GWA 會無視你的確認刪除指令碼,直接從後台把 "/orders/delete/1024" 載入,也就意味著 1024 訂單已經被刪除了。
GWA 發布後,很多網站出現了很多莫名其妙的問題,資料無故丟失,商品自動加入了使用者的購物車,使用者無端地被扣款…
一時問題很嚴重,後來發現的原因的所在,就是網站開發人員沒有遵守 HTTP 約定,沒有弄明白 GET 和 POST 的區別。
而如今,Google發布的 Chrome 瀏覽器,類似的加速功能整合了進去,你可以在 設定 - 顯示進階設定 裡面看得到:
所以,對伺服器有改變的一定要用 POST,GWA 和類似的外掛程式不會提交 POST 表單加速的。
刪除、查看使用者資訊收費(比如人才網、婚戀網)、加入購物車等操作還是放在 POST 表單中用 Button 來吧。
再回頭讀維基百科中對 Safe Methods 的說明,相信你會明白很多。
注意:但也不是所有對伺服器有改變的都要用 POST,比如你點擊本文下面的 前一篇博文連結 ,我的文章訪問量可能+1,對伺服器有所改變,但這種改變是輕微的,影響不大(相對刪除、扣款來說),可以放心的使用連結(GET 方式)。
基它一些區別:
- 使用 GET 表單查詢,查詢結果頁面可以收藏;POST 表單不行。
- 向伺服器傳送檔案只能使用 POST 表單。
能想到的大致這些吧。
感言
之前,我曾學習 ASP.NET 多年,但對 HTTP 幾乎一無所知,WebForm 封裝了一切:
- 不用去考慮 POST、GET,只需知道 Postback;
- 不用多考慮值來回傳遞,因為有 ViewState;
- 不用關心 Html,因為有服務端控制項。
更悲哀的是,我有很長一段時間都認為一個頁面上只能有一個 Form。
後來做了一段時間 WinForm 後,開始學習 ASP.NET MVC,開始逐步瞭解 Html、Http 等等,也開始知道了 Post-Redirect-Get 模式等等。
看到很多人淺淺討論 GET 和 POST,感到很無奈,WebForm 誤人啊。要想進步,還是學學 ASP.NET MVC 吧!