HTTP的GET跟POST Method我想大家應該都略知一二,本篇主要將觀念帶一下,並用幾個簡單的範例讓大家了解兩者間的差異,我想在開始之前大家先看看W3C對GET跟POST的定義吧:HTTP/1.1: Method Definitions(請看9.3與9.5兩節)
除了以上的定義外,我想以下我翻成比較口語化的用詞吧:
1.GET透過URL的QueryString來傳送想要的資料;POST透過Form submission來傳送想要的資料
2.GET因為透過QueryString來傳送資料,會有URL最大長度限制(可參考[ASP.NET]ASP.NET 4.0 設定QueryString的最大長度);POST則無此限制POST如果透過Send來傳送資料則不會有此問題,若透過URL來傳送一樣會有相同的狀況
3.GET因為透過QueryString來傳送資料,因此也會衍生一些安全性議題,最少敏感性資料不該透過URL來傳送;POST則不會直接洩漏資料於URL上POST如果透過Send來傳送資料則不會有此問題,若透過URL來傳送一樣會有相同的狀況
4.GET會被cache;POST則不會(預設)
以下簡單用幾個範例驗證一下以上四點,以下都使用XMLHttp來實作,以下先描述一下前置準備:
我先在畫面上拉兩個html button,然後分別呼叫SetGET()與SetPOST兩個function,我們可以看到SetGET中,xmlhttp.Open透過URL將Data帶過去,而SetPOST中則透過xmlhttp.Send將Data帶過去GetValue.aspx:
01 | <%@ Page Language="C#" AutoEventWireup="true" CodeFile="GETnPOST.aspx.cs" Inherits="GETnPOST" %> |
06 | < script language = "javascript" > |
07 | var Data = "< root >< title1 >XML</ title1 >"+ |
09 | "< Record >< Column1 >col1</ Column1 >< Column2 >col2</ Column2 >< Column3 >col3</ Column3 >< Column4 >col4</ Column4 >< Column5 >col5</ Column5 >< Column6 >col6</ Column6 >< Record >"+ |
10 | "< Record >< Column1 >col1</ Column1 >< Column2 >col2</ Column2 >< Column3 >col3</ Column3 >< Column4 >col4</ Column4 >< Column5 >col5</ Column5 >< Column6 >col6</ Column6 >< Record >"+ |
11 | "< Record >< Column1 >col1</ Column1 >< Column2 >col2</ Column2 >< Column3 >col3</ Column3 >< Column4 >col4</ Column4 >< Column5 >col5</ Column5 >< Column6 >col6</ Column6 >< Record >"+ |
12 | "< Record >< Column1 >col1</ Column1 >< Column2 >col2</ Column2 >< Column3 >col3</ Column3 >< Column4 >col4</ Column4 >< Column5 >col5</ Column5 >< Column6 >col6</ Column6 >< Record >"+ |
13 | "< Record >< Column1 >col1</ Column1 >< Column2 >col2</ Column2 >< Column3 >col3</ Column3 >< Column4 >col4</ Column4 >< Column5 >col5</ Column5 >< Column6 >col6</ Column6 >< Record >"+ |
18 | var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); |
19 | var objXML = new ActiveXObject("Microsoft.XMLDOM"); |
20 | var strURL = "GetValue.aspx?Data="; |
21 | xmlhttp.Open('GET', strURL+Data, false); |
23 | var returnValue = xmlhttp.ResponseText; |
29 | var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); |
30 | var objXML = new ActiveXObject("Microsoft.XMLDOM"); |
31 | var strURL = "GetValue.aspx"; |
32 | xmlhttp.Open('POST', strURL, false); |
34 | var returnValue = xmlhttp.ResponseText; |
42 | < form id = "form1" runat = "server" > |
44 | < input id = "Button1" type = "button" value = "GET" onclick = "SetGET()" /> |
45 | < input id = "Button2" type = "button" value = "POST" onclick = "SetPOST()" /></ div > |
在GetValue.aspx中我只在Page_Load中加入一行,用來回傳我送過去的ContentLength與Server的時間:
1 | protected void Page_Load( object sender, EventArgs e) |
3 | Response.Write( "ContentLength" + Request.InputStream.Length.ToString() + " Time:" + DateTime.Now.ToString()); |
1.GET透過URL,POST透過Form submission傳送資料
這一項透過以上的預先準備我們就可以看到GET/POST兩者有以下的不同。
測試的結果就是這樣:
這邊要特別留意的,如果我就是不想遵守GET用URL的原則,我就要直接在Open中用GET,然後Send中還是送出我要的資料,不寫null:
我在畫面上多拉了一個按鈕來做這件事,結果發現只要我在Send中有放資料,就會強制以POST來送出我的Form:
2.GET透過QueryString來傳送Data會有最大傳送資料限制
這一點請直接參考[ASP.NET]ASP.NET 4.0 設定QueryString的最大長度,而超過最大長度限制會有404的Error:
3.GET透過QueryString傳送Data會有安全性問題
這個問題其實只跟QueryString本身有關連,有些人撰寫程式習慣使用以下寫法:
1 | GetValue.aspx?user=0123&form=Inbox |
讓人不期然就會想試看看以下寫法,看能不能直接取得老闆的收件匣:
1 | GetValue.aspx?user=0001&form=Inbox |
其實我們只要緊記,重要的資料絕對不透過URL來傳送就好,以上面這個範例來說,user的帳號一般我們直接放在Session中就可以免掉這個問題了。
4.GET會被cache,POST預設則不會
使用GET,如果request的網址沒有變動,則Result會是cache的,這意謂著我們取得的不見得是最新的資訊,
我們以下面這個案例來說明,我前面有提到我在GetValue.aspx中有回傳Server的時間,如果沒有cache的話應該每次按都不同,但我們實際以GET來測試就會發現取得的時間是11:27分,但實際的時間是11:44分,同樣的事情我們用POST來處理就不會有這樣的問題:
這個問題在網路上有找到一個案例:
GET、POST與cache的關係
除了以上四點差異外,透過開發者工具,我們在Request Headers/Request Body兩個頁籤也有一些差別,主要是POST有透過Send將資料送出去,因此Content-Length跟Body中都有內容,而GET則沒有,
也因此衍生了一些差異,POST因為要多送Request Body中的內容,若以達到相同功能來說,GET會比POST快一些。
以上大概比較了一下GET/POST的差異,希望對大家有幫助,我想依此而衍生出來的issue應該非常非常多,歡迎大家補充。
備註:感謝璉璉大的提醒,為了避免誤會,我把用詞改了一下,POST如果透過Send來傳送資料則不會有此問題,若透過URL來傳送一樣會有與GET相同的狀況
參考資料:
The Definitive Guide to GET vs POST
HTTP/1.1: Method Definitions
Methods GET and POST in HTML forms - what's the difference?
GET、POST與cache的關係
<PARAM NAME="WMode"