當使用者填寫頁面<FORM>內容時所提供的全部值,或在瀏覽器網址列輸入在URL後的值,透過Form和QueryString集合為ASP腳本所用。這是在ASP程式碼中存取值的簡單方法。
1. 訪問ASP集合的一般技術
大多數ASP集合與在VB中見到的普通集合相差不多。實際上,它們是值的數組,但能透過使用一個文字字串鍵(對大小不敏感)以及一個整數索引進行存取。因此,假如客戶端Web頁所包含的<FORM>如下:
<FORM ACTION=”show_request.asp” METHOD=”POST”>
FirstName:<INPUT TYPE=”TEXT” NAME=”FirstName”>
LastName:<INPUT TYPE=”TEXT” NAME=”LastName”>
<INPUT TYPE=”SUBMIT” VALUE=”Send”>
</FORM>
可透過存取ASP的Form集合來存取其控制項內的值:
strFirstName = Request.Form(“FirstName”)
strLastName = Request.Form(“LastName”)
也可使用窗體中控制項的整數索引,索引的範圍從在HTML中第一個定義的控制項開始,然後依照定義的順序排序:
strFirstName = Request.Form( 1)
strLastName = Request.Form(2)
然而,後面的這種以整數為索引的技術不建議使用,因為一旦有HTML中的控件發生了變化,或者插入一個新的控件,則ASP程式碼將得到錯誤的值。進一步而言,對於閱讀程式碼的人來講,極容易混淆。
1) 存取集合的全部值
可以透過引用集合把整個Form上的一系列值變成單一的字元變量,且不用提供鍵或索引。
StrAllFormContent = Request.Form
假如文字方塊包含值Priscilla和Descartes,則Request.Form語句將傳回下列字元:
FirstName=Priscilla&LastName=Descartes
注意,提供的值是以名稱/值對的形式出現的(即控制項名稱=控件值),並且每一對名稱/值相互之間是用符號“&”相分隔的。假如打算把窗體中的內容傳遞單獨的,希望得到值的標準格式的可執行應用程式或DLL,這個技術是很有用的。然而,一般說來,都是透過以窗體中控制項的名稱為文字鍵來存取集合中的內容。
2) 遍歷一個ASP集合
有兩種方式遍歷一個ASP集合中的所有成員,方式與一般VB集合的基本相同。每個集合提供一個Count屬性,傳回的是集合中條目數量。可透過使用一個整數索引使用Count屬性來遍歷。
為 intLoop=1 To Request.Form.Count
Response.Write Request.Form(intLoop) & “<BR>”
Next
假如先前的窗體包含Priscilla和Descartes值的兩個文字框,將得到以下結果:
Priscilla
Descartes
然而,更好的方法是使用For Each...Next結構。
為 Each objItem In Request.Form
Response.Write objItem & “=” & Request.Form(objItem) & “<BR>”
Next
這帶來的好處是既可以存取控制項的名稱又可存取其值。上述程式碼將得到以下結果:
FirstName = Priscilla
LastName = Descartes
注意,有些瀏覽器回到ASP的<FORM>值可能與頁面上顯示的順序不盡相同。
3) 集合成員的多值性
在某些情況下,ASP集合中的各個成員可能不只一個值,這種情況發生在HTML定義中有幾個控制項有相同Name屬性時。例如:
<FORM ACTION=”Show_request.asp” METHOD=”POST”>
<INPUT TYPE=”TEXT” NAME=”OtherHobby”>
<INPUT TYPE=”TEXT” NAME=”OtherHobby”>
<INPUT TYPE=”TEXT” NAME=”OtherHobby”>
<INPUT TYPE=”SUBMIT” VALUE=”Send”>
</FORM>
在Form集合中,將為「OtherHobby」建立一個條目。然而,它將包括從三個文字方塊中得到的值。假如在提交時,使用者留下了一個或多個為空,則傳回的值為空字串。假如使用者在第一和第三個文字方塊分別輸入Gardening和Mountaineering,第二個文字方塊為空,在我們的ASP程式碼中存取Request.Form(“OtherHobby”),將傳回字串: Gardening
, ,Mountaineering
為了能夠在這種情況下,存取單一值,可以用複雜一些的程式碼: For Each
objItem In Request.Form
If Request.Form(objItem).Count >1 Then 'More than one value in this item Response.Write objItem & “:<BR>”
For intLoop = 1 To Request.Form(objItem).Count
Response.Write “Subkey” & intLoop & “value = “& Request.Form(objItem) (intLoop) & “<BR>”
Next
Else
Response.Write objItem & “ = ” & Request.Form(objItem) & “<BR>”
End If
Next
對於前面的包含三個OtherHobby控制項的窗體實例,這將會傳回:
OtherHobby:
Subkey 1 value = Gardening
Subkey 2 value =
Subkey 3 value = Mountaineering
然而,由於很少給多個文字框相同的名字,因此這種技術很少用到。
a) HTML中的單選或選頁按鈕控制項
在HTML中,需要給幾個控制項相同的Name屬性的情況是單選(或選項)按鈕,例如:
<FORM ACTION=”show_request.asp” METHOD=” POST”>
I live in:
<INPUT TYPE=”RADIO” NAME=”Country” VALUE=”AM”>America<BR>
<INPUT TYPE=”RADIO” NAME=”Country” VALUE=”EU”>Europe<BR>
<INPUT TYPE=”RADIO” NAME=”Country” VALUE=”AS”>Asia<BR>
<INPUT TYPE=”SUBMIT” VALUE=”Send”>
</FORM>
因為使用者只能選擇多項中的一個(這就是給它們相同的名字的原因),將只得到一個回傳值,瀏覽器只能發送所選控制項的值。因此,假如這個窗體的用戶已經選擇了“Europez”,將得到這個條目,通過遍歷Form集合得到其值:
Country = EU
由於為每個控件提供了不同的VALUE屬性,反映了每個條目所對應的國家或地區的名稱。假如省略了VALUE屬性,瀏覽器將傳回的值為“on”,因此將得到:
Country = on
這是不常用到的,因此一般對使用相同名稱的單選控制項使用VALUE屬性。
b) HTML複選框控制項
當一個窗體中HTML原始碼包含一個複選框控制項時,一般都會給予唯一的名稱,例如:
<FORM ACTION=”show_request.asp” METHOD=”POST”>
I enjoy:
<INPUT TYPE=”CHECKBOX” NAME=”Reading” CHECKED> Reading
<INPUT TYPE=”CHECKBOX” NAME=”Eating”> Eating
<INPUT TYPE=”CHECKBOX” NAME=”Sleeping”> Sleeping
<INPUT TYPE=”SUBMIT” VALUE=”Send”>
</FORM>
在這種情況下,提交窗體時,假如僅是第一和第三個複選框被選中(加標記),遍歷Form集合時,會得到下列值:
Reading = on
Sleeping = on
然而,假如為每個複選框提供一個值,把這個值發往伺服器代替字串「on」。例如窗體如下:
<FORM ACTION=”show_request.asp” METHOD=”POST”>
I enjoy:
<INPUT TYPE=”CHECKBOX” VALUE=”Hobby025” NAME=”Hobby” CHECKED>_
Swimming
<INPUT TYPE=”CHECKBOX” VALUE=”Hobby003” NAME=”Hobby” CHECKED>_
Reading
<INPUT TYPE=”CHECKBOX” VALUE=”Hobby068” NAME=”Hobby”>Eating
<INPUT TYPE=”CHECKBOX” VALUE=”Hobby010” NAME=”Hobby”>Sleeping
<INPUT TYPE=”SUBMIT” VALUE=”Send”>
</FORM>
如果除第三個複選框外,全部提交,在Request.Form集合會產生下列結果:
Hobby = Hobby025, Hobby003, Hobby010
假如編寫更複雜一些集合遍歷程式碼,如先前所述(單獨顯示每個子鍵),就得到這樣結果:
Hobby:
Subkey 1 value = Hobby025
Subkey 2 value = Hobby003
Subkey 3 value = Hobby010
要注意的是兩種情況,沒有選取的控制項根本不回傳任何值。在第一種情況的結果裡,沒有欺騙性的逗號,第二種情況也沒有空值。這與上述的使用文字方塊的相當的測試的結果不一樣。使用文字方塊時,每個文字方塊都會傳回一個值,即使是一個空字串。這是瀏覽器造成這樣的結果。因此在ASP程式碼中存取集合時,請注意這個問題。
上述情況一個棘手的負作用是使用複選框時,複選框值的索引與在原始的HTML中控件的位置沒有任何联系,在上述的例子中第四個複選框的子鍵數為3 ,因為當窗體提交時,第二個控制項沒有選取。
c) HTML清單控制項
HTML中的<SELECT>標記用來產生標準的下拉列錶框,其值以有趣的混合方式表示。下列的窗體建立了包含5個值可供使用者選擇,由於包含了MULTIPLE屬性,因此可以透過選擇時按下Shift或Ctrl鍵,選擇不只一個的條目。
<FORM ACTION=”show_request.asp” METHOD=”POST”>
<SELECT NAME=”Hobby” SIZE=”5” MULTIPLE>
<OPTION VALUE=”Hobby001”>Programming</OPTION>
<OPTION VALUE=”Hobby025”>Swimming</OPTION>
<OPTION VALUE=”Hobby003”>Reading</OPTION>
<OPTION VALUE=”Hobby068”>Eating</OPTION>
<OPTION VALUE=”Hobby010”>Sleeping</OPTION>
</SELECT><P>
<INPUT TYPE=”SUBMIT” VALUE=”Send”>
</FORM>
這種特殊的情況回傳的是在Form集合中單一條目,它包含選擇的值(單一的<OPTION>標記中指定的VALUE屬性),用逗號分隔:
Hobby = Hobby025, Hobby003, Hobby010
假如使用更複雜一些的集合遍歷程式碼(單獨顯示每個子鍵),將得到:
Hobby:
Subkey 1 value = Hobby025
Subkey 2 value = Hobby003
Subkey 3 value = Hobby010
這與上述相同名稱的複選框的情況相同。事實上可以認為SELECT清單是一列複選框的清單供選擇(不是選取)對應的條目。
然而,列錶框也有指定的值,假如在<OPTION>標記中設定VALUE屬性,將得到的是選擇的選項的文字內容,Request.Form集將包含這樣一個項目:
Hobby = Swimming, Reading, Sleeping
並且,同樣,複雜一些的集合遍歷程式碼將傳回如下結果:
Hobby:
Subkey 1 value = Swimming
Subkey 2 value = Reading
Subkey 3 value = Sleeping
當然,假如單一項目被選擇,且在<OPTION>中提供了VALUE屬性,得到結果包含的僅是:
Hobby = Hobby025
如果沒有提供VALUE屬性,得到:
Hobby = Swimming
這允許既可以缺省(即無VALUE)顯示選項文本,也可做相應的改變。後一種情況在某些情況下是極為有用的,如要顯示(一個說明的字串)和傳遞一個完全不同的內容(如用一個短碼代表一個說明性的字串)。
d) HTML提交和圖像控制項
複選框和單選框是布林型控制項的例子,選取或選取返回的為“on”,不像文字方塊和大多數其他的HTML控件,瀏覽器不包含沒有選取或沒有選擇的控制項的值。
還有另外一種常用的布林控制項,稱為HTML按鈕。如<INPUT TYPE=”SUBMIT”>、<INPUT TYPE=”RESET”>、<INPUT TYPE=”IMAGE”>、<INPUT TYPE=”BUTTON”>和<BUTTON>…>/UTU類型。
BUTTON類型的控制不傳回任何值,因其對窗體沒有直接的影響。即使使用用來呼叫窗體的Submit方法,瀏覽器在任何請求中將不包含BUTTON類型控制項的值。同樣,一個<INPUT TYPE=”RESET”>按鈕的值也絕不會發往伺服器。
然而,輸入按鈕控制項SUBMIT和IMAGE類型實際提交窗體給伺服器,其VALUE屬性包含窗體的其他控制項的值(只要在HTML定義中包含一個NAME屬性)。例如,這個窗體可能是精靈類型Web應用程式的一部分,允許使用者一步一步進行或取消進程:
<FORM ACTION=”show_request.asp” METHOD=”POST”>
<INPUT TYPE=”SUBMIT” NAME=”btnSubmit” VALUE=”Next”>
<INPUT TYPE=”SUBMIT” NAME=”btnSubmit” VALUE=”Previous”>
<INPUT TYPE=”SUBIMT” NAME=”btnSubmit” VALUE=”Cancel”>
</FORM>
在一個窗體中,可以包含多個SUBMIT按鈕。在這種情況下,應該給每一個按鈕唯一的VALUE屬性,如上所示。當一個窗體被提交時,遍歷Request.Form集合的值,將產生一個值,這個值依賴於按下哪個按鈕用於提交這個窗體。假如使用者按下的「Previous」按鈕,將會得到:
btnSubmit = Previous
因此,可查詢Request.Form集合來決定下一個顯示的頁面,例如:
Select Case Request.Form(“btnSubmit”)
Case “Next”
Response.Redirect “page_3.asp”
Case “Previous”
Response.Redirect “page_1.asp”
Case “Cancel”
Response.Redirect “main_menu.asp”
End Select
同時,也可依需求對每個按鈕使用不同的NAME屬性。並選擇其值包含在Form集合中的控制項名稱。在控制項沒有一個完整的標記而是隨後跟著較長的文字標籤的情況下,極為有用,如下圖所示。
此畫面上的介面由下列程式碼產生:
<FORM ACTION=”show_request.asp” METHOD=”POST”>
<B>What do you want to do now?</B><P>
<INPUT TYPE=”SUBMIT” NAME=”btnNext” VALUE= ”> Go on the next page<P>
<INPUT TYPE=”SUBMIT” NAME=”btnPrevious” Value=” ”> GO back to the previous page<P>
<INPUT TYPE=”SUBMIT” NAME=”btnCancel” VALUE=” ”> Cancel and go back to the main menu page<P>
</FORM>
在ASP頁面中,接收到資料後,可以檢查按扭名稱提供的值來判斷按下的是哪個按鈕。
If Len(Request.Form(“btnNext”)) Then Response.Redirect “page_3.asp”
If Len(Request.Form(“btnPrevious”)) Then Response.Redirect “page_1.asp”
If Len(Request.Form(“btnCancel”)) Then Response.Redirect “main_menu.asp”
這個工作是查詢一個鍵上的ASP集合,如果不存在則傳回一個空的字串。換句話說,如果第二個按鈕(previous頁)按下,則Request.Form(“btnNext”)的值是一個空字串,則其長度為零而不至於產生一個錯誤。當第二個按鈕按下時,則在Form集合中這個項目的值Request.Form(“btnPrevious”),將是“ ”其長度大於零。
e) 提高使用Request集合的效率
訪問一個ASP集合來下載一個值是費時的需計算資源的過程,因為這個操作包含了一系列對相關集合的搜索,這比訪問一個局部變量要慢得多。因此,如果打算在頁面中多次使用集合中的一個值,則應考慮將其存貯成為局部變量,例如:
strTitle = Request.Form(“Title”)
strFirstName = Request.Form(“FirstName”)
strLastName = Request.Form(“LastName”)
If Len(stTitle) Then strTitle = strTitle & “ “
If strFirstName = “ “ Then
StrFullName = strTitle & “ “ & strLastName
ElseIf Len(strFirstName) = 1 Then
StrFullName = strTitle & strFirstName & “· “ & strLastName
Else
StrFullName = strTitle & strFirstName & “ ” & strLastName
End If
f) 搜尋所有的Request集合
在某些情況下,可能知道一個值的鍵名會出現在Request集合中,但不能準確地知道是哪一個集合。例如,假如有幾個頁面(或一個頁面的不同段落)發送一個值給同一個ASP腳本,它可能在Form或QueryString集合中出現。
要看一個值為什麼可能出現在不同的集合中,考慮一下這種情況:使用了<A>超級連結元素請求一個頁面。在這種情況下,增加一個值到請求的唯一方法是把它加到URL上。然而,同樣的值可能已出現在另一個頁面的<FORM>中,或同一頁面不同部分:
...
<FORM ACTION=”process_page.asp” METHOD=”POST”>
<INPUT TYPE=”SUBMIT” NAME=”page” VALUE=”Next”>
<INPUT TYPE=”SUBMIT” NAME=”page” VALUE=”Previous”>
<INPUT TYPE=”SUBMIT” NAME=”page” VALUE=”Help”>
</FORM>
……
……
For help go to the <A HREF=”process_page.asp?page=Help”>Help Page</A>
……
在這種情況下,按下窗體上的Help按鈕,將發送Request.Form集合中一對名稱/值「page=Help」。然而,按下<A>超級連結也可能發送名稱/值“Page=Help”,但這次卻是在QueryString集合裡。要存取這個值,可使用ASP Request物件的一個特殊功能:
strPage = Request(“page”)
這將依序搜尋全部的集合-QueryString、Form、Cookies、ClientCertificate、ServerVariables,直到發現第一個符合值的名稱。這樣做比直接存取適當的集合效率低,而且是不安全的,除非能絕對保證這個值不會出現在另一個集合中。
例如,可能希望蒐集滿足客戶請求的Web伺服器的名稱,這透過出現在每個查詢中的Request.ServerVariables集合中尋找「SERVER_NAME」來實現。然而,只有任一其他的集合也包含名為「server_name」的值(記住鍵名不區分大小寫),當使用Request(“server_name”)時,得到的是錯誤的結果。使用Reqeust.ServerVariables(“server_name”)句法,我們將很難進行錯誤追蹤。
總而言之,使用「搜尋全部集合」技術要格外小心,且只在沒有其他技術能夠提供你需要的結果時使用。
g) 在訪問其他的集合
本文的這一節裡,已經集中討論了Form集合,這可能是使用得最多的一個。然而,所有這些技術同樣適用於其他的對象。包括那些由Request物件提供的(即Form、QueryString、Cookies、ServerVariables和ClientCertificate)集合,以及由Response物件提供的cookies(及其他物件提供的集合)。
我們將簡短了解一個值如何進入一個QueryString集合,及其優點和不足。然而,同時這兩個Cookies集合有額外的功能,可以讓使用cookie更加方便,以下討論這個內容。