注意get和post對應的enctype屬性有區別。enctype有兩個值,默認值為application/x-www-form-urlencoded,而另一個值multipart/form-data只能用于post。
2.3 提交的數據的長度
HTTP specification并沒有對URL長度進行限制,但是IE將請求的URL長度限制為2083個字符,從而限制了get提交的數據長度。測試表明如果URL超出這個限制,提交form時IE不會有任何響應。其它瀏覽器則沒有URL的長度限制,因此其它瀏覽器能通過get提交的數據長度僅受限于服務器的設置。
而對于post,因為提交的數據不在url中,所以通常可以簡單地認為數據長度限制僅受限于服務器的設置。
2.4 緩存
由于一個get得到的結果直接對應到一個URI,所以get的結果頁面有可能被瀏覽器緩存。而post一般則不能,參考5。
2.5 引用和SEO
出于和上面相同的原因,我們可以用一個URI引用一個get的結果頁面,而post的結果則不能,所以必然不能被搜索引擎搜到。
3. 服務端的處理
在服務端的ASP.NET程序中,對于get,我們用Request.QueryString[control-name]來取得對應的=current-value;對于post,我們用Request.Form[control-name]。
我們也可以籠統地使用Request[control-name]。但這樣做的效率不如前者。我們可以用下面的程序比較Request.QueryString和Request的效率:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_PreInit(object sender, EventArgs e)
{
if(Request["InputString"] != null)
{
int count = 1000000;
DateTime start;
DateTime end;
string value = "";
start = DateTime.Now;
for(int i = 0;i < count;i++)
{
value = Request.QueryString["InputString"];
}
end = DateTime.Now;
double requestGet = (end - start).TotalSeconds;
start = DateTime.Now;
for(int i = 0;i < count;i++)
{
value = Request["InputString"];
}
end = DateTime.Now;
double request = (end - start).TotalSeconds;
compare.InnerHtml = requestGet.ToString() + " / " + request.ToString() + " = " + (requestGet / request).ToString();
get.InnerHtml = value;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Request.QueryString / Request</title>
</head>
<body>
<form method="get" action="FormGet.aspx">
<div>
<input type="text" name="InputString" /><input type="submit" value="Post" /><br />
Get: <span runat="server" id="get"></span><br />
Request.QueryString / Request: <span runat="server" id="compare"></span>
</div>
</form>
</body>
</html>
同樣的辦法我們可以比較Request.Form和Request。
最后得到的結果(Request.QueryString[control-name] / Request[control-name]和Request.Form[control-name] / Request[control-name])大多數時候是小于1的。因此,我們因該盡量用Request.QueryString或Request.Form來代替Request。
4. 正確地使用get和post
W3C的官方建議是:當且僅當form是冪等(idempotent)的時候,使用get。冪等是一個數學上的術語,其定義是:對于一個函數f : D -> D,如果D中的所有x滿足f (f x) = f x,那么這個函數是冪等的。HTTP specification(比如RFC 2616)中,將冪等解釋為:多次相同請求產生的副作用,和一次請求的副作用相同。
打個比方,如果你提交一個form會從Google上查詢一個關鍵詞,那么我們可以認為這個form是冪等的,因為1次提交和10次提交的副作用是差不多的(10次查詢可能會多消耗一些電能);如果你提交一個form是訂購一個終極大黃蜂(Utimate bumblebee),那么這就不是冪等的:要是你不小心多提交了1次form的話,你可能會被老婆亂罵,你不小心又提交了10次的話,你可能就破產了——一次提交和多次提交的副作用明顯不同,所以這不是冪等的。
所以,一般來說,如果提交這個請求純粹只是從服務端獲取數據而不進行其他操作,并且多次提交不會有明顯的副作用,應該使用get。比如:
如果提交這個請求會產生其它操作和影響,就應該使用post。比如:
- 修改服務器上數據庫中的數據;
- 發送一封郵件;
- 刪除一個文件。
另一個要考慮的因素是安全性。見2.1。
5. 瀏覽器差異
6. 參考