小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

理解form的get和post(轉(zhuǎn)載)

 集微筆記 2013-12-08

在HTML中,form元素用method屬性來指定有兩種不同的提交方法,即"get"(默認值)和"post"。


1. get和post的定義
W3C的HTML 4.01 specification說,form元素的method屬性用來指定發(fā)送form的HTTP方法。


使用get時,form的數(shù)據(jù)集(形如control-name=current-value的鍵值對)被附加到form元素的action屬性所指定的URI后面;
使用post時,form的數(shù)據(jù)集(形如control-name=current-value的鍵值對)被包裝在請求的body中并被發(fā)送。
這可以簡單地理解為,get僅僅是拼接一個URI,然后直接向服務(wù)器請求數(shù)據(jù)(需要提交給服務(wù)器的數(shù)據(jù)集包含在URI中)。比如:



<form method="get" action="FormGet.aspx">  
    
<input type="text" name="ProductID" value="1" />  
    
<input type="submit" value="Get" />  
</form> 

 


 


這個form在提交的時候,會產(chǎn)生這樣能夠一個get請求:FormGet.aspx?ProductID=1。


而post會把form的數(shù)據(jù)集,即ProductID=1這個鍵值對包裝在請求的body中,發(fā)送給服務(wù)器,然后向服務(wù)器請求數(shù)據(jù)。對于:



<form method="post" action="FormPost.aspx">  
    
<input type="text" name="ProductID" value="1" />  
    
<input type="submit" value="Get" />  
</form>  

 


 


這樣一個form在提交時,我們將看到一個干凈的URI:FormPost.aspx。因為數(shù)據(jù)不是拼接在URI中。


2. get和post的區(qū)別
2.1 安全性
如果用get提交一個驗證用戶名和密碼的form,一般認為是不安全的。因為用戶名和密碼將出現(xiàn)在URL上,進而出現(xiàn)在瀏覽器的歷史記錄中。顯然,在對安全性有要求的情況下,應(yīng)該使用post。


2.2 編碼
HTML 4.01 specification指出,get只能向服務(wù)器發(fā)送ASCII字符,而post則可以發(fā)送整個ISO10646中的字符(如果同時指定enctype="multipart/form-data"的話)。


注意get和post對應(yīng)的enctype屬性有區(qū)別。enctype有兩個值,默認值為application/x-www-form-urlencoded,而另一個值multipart/form-data只能用于post。


2.3 提交的數(shù)據(jù)的長度
HTTP specification并沒有對URL長度進行限制,但是IE將請求的URL長度限制為2083個字符,從而限制了get提交的數(shù)據(jù)長度。測試表明如果URL超出這個限制,提交form時IE不會有任何響應(yīng)。其它瀏覽器則沒有URL的長度限制,因此其它瀏覽器能通過get提交的數(shù)據(jù)長度僅受限于服務(wù)器的設(shè)置。


而對于post,因為提交的數(shù)據(jù)不在url中,所以通??梢院唵蔚卣J為數(shù)據(jù)長度限制僅受限于服務(wù)器的設(shè)置。


2.4 緩存
由于一個get得到的結(jié)果直接對應(yīng)到一個URI,所以get的結(jié)果頁面有可能被瀏覽器緩存。而post一般則不能,參考5。


2.5 引用和SEO
出于和上面相同的原因,我們可以用一個URI引用一個get的結(jié)果頁面,而post的結(jié)果則不能,所以必然不能被搜索引擎搜到。


3. 服務(wù)端的處理
在服務(wù)端的ASP.NET程序中,對于get,我們用Request.QueryString[control-name]來取得對應(yīng)的=current-value;對于post,我們用Request.Form[control-name]。


我們也可以籠統(tǒng)地使用Request[control-name]。但這樣做的效率不如前者。我們可以用下面的程序比較Request.QueryString和Request的效率:


復(fù)制代碼

<%@ Page Language="C#" %>   
  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd">   
  
<mce: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;   
        }   
    }   
// --></mce:script>   
  
<html xmlns="http://www./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>  
復(fù)制代碼

 


 


同樣的辦法我們可以比較Request.Form和Request。


最后得到的結(jié)果(Request.QueryString[control-name] / Request[control-name]和Request.Form[control-name] / Request[control-name])大多數(shù)時候是小于1的。因此,我們因該盡量用Request.QueryString或 Request.Form來代替Request。


4. 正確地使用get和post
W3C的官方建議是:當(dāng)且僅當(dāng)form是冪等(idempotent)的時候,使用get。冪等是一個數(shù)學(xué)上的術(shù)語,其定義是:對于一個函數(shù)f : D -> D,如果D中的所有x滿足f (f x) = f x,那么這個函數(shù)是冪等的。HTTP specification(比如RFC 2616)中,將冪等解釋為:多次相同請求產(chǎn)生的副作用,和一次請求的副作用相同。


打個比方,如果你提交一個form會從Google上查詢一個關(guān)鍵詞,那么我們可以認為這個form是冪等的,因為1次提交和10次提交的副作用是差不多的(10次查詢可能會多消耗一些電能);如果你提交一個form是訂購一個終極大黃蜂(Utimate bumblebee),那么這就不是冪等的:要是你不小心多提交了1次form的話,你可能會被老婆亂罵,你不小心又提交了10次的話,你可能就破產(chǎn)了——一次提交和多次提交的副作用明顯不同,所以這不是冪等的。


所以,一般來說,如果提交這個請求純粹只是從服務(wù)端獲取數(shù)據(jù)而不進行其他操作,并且多次提交不會有明顯的副作用,應(yīng)該使用get。比如:


搜索引擎的查詢:http://www.google.com/search?q=yandixin
分頁:ArticleList.asp?Page=1。
如果提交這個請求會產(chǎn)生其它操作和影響,就應(yīng)該使用post。比如:


修改服務(wù)器上數(shù)據(jù)庫中的數(shù)據(jù);
發(fā)送一封郵件;
刪除一個文件。
另一個要考慮的因素是安全性。見2.1。


5. 瀏覽器差異
IE 6:URL長度限制為2083個字符;post之后,刷新頁面不會自動重新post數(shù)據(jù),會出現(xiàn)警告;

并且,在后退的過程中有可能出現(xiàn)“Page has Expired”(通常是向自己post,然后后退時):

微軟的技術(shù)支持人員號稱“this is not a bug or problem specified to the ASP.NET but a security feature of the IE Browser”,并且說“You can also inform your users of this”,實在是荒唐。另外,一篇KB也提到這個問題,說將Response.CacheControl設(shè)為"Public"即可,經(jīng)測試僅在第一次后退時有效。
IE 7:和IE 6相同;
Firefox 2.0.0.11:刷新頁面不會自動重新post數(shù)據(jù),會出現(xiàn)警告;



Opera 9.24:正常(自動post數(shù)據(jù));
Safari 3.0.4:post之后,刷新頁面、前進、后退都不會自動重新post數(shù)據(jù),會出現(xiàn)警告。


6. 參考


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多