Cookies的值比ASP其他集合(例如Form和ServerVariables)的值要複雜得多。 Cookie是一小塊由瀏覽器存貯在客戶端系統上的文本,且隨同每次請求發送至它們應用於的網域中的伺服器。
ASP使得應用cookie較為容易,可從Request物件的Cookies集合中取得所有隨同請求發出的cookie值,並可建立或修改cookie,透過Response物件的Cookies集合傳回給使用者。
Cookie包含可用兩種方式構造的信息,單值cookie提供其值給代碼是透過一個一般的類ASP集合。然而,集合的每個成員可能本身也是一個集合,包含這種資訊的cookie通過稱為多值(multiple-Value)cookie。
建立一個單值的cookie較為簡單,如下所示:
Response.Cookies(“item-name”) = “item-value”
建立一個多值的cookie,可以使用以下指令:
Response.Cookies(“item-name” )(“sub-item-name”) = “sub-item-value”
設定cookie應用的域及路徑及其有效期,我們使用:
Response.Cookies(“item-name”).domain = “domain-url”
Response.Cookies(“item-name”).path = “virtual-path”
Response.Cookies(“item-name”).expires = #date#
通常,客戶只在對創建cookie的目錄中的頁面提出請求時,才將cookie隨請示發住伺服器。透過指定path屬性,可以指定網站中何處這個cookie是合法的,而這個cookie將隨請求發送。如果cookie隨整個網站的頁面請求發送,則設定path為「/」。
如果Expires屬性沒有設置,關閉目前的瀏覽器實例時,cookie將會自動消除。
注意,我們在向瀏覽器發送任何輸出時,已經建立了cookie。因為,這些cookie是頁面HTTP標頭的一部分。
在ASP 3.0中,緩衝的預設狀態是開啟的,且沒有輸出被傳送,除非使用Response.Flush指定做這個工作或頁面已到最後。這意味著創建cookie的程式碼可以在頁面上的任何位置,直到任何輸出「刷新」(flush)到客戶端前,它都可以被執行。
若要讀取現有的cookie,請使用Request.Cookies集合。可以單獨存取其中的項目,方法類似於創建它們時使用的方法。
StrSingleValue = Request.Cookies(“item-name”)
StrSubItemValue = Request.Cookies(“item-name”)(“sub-item-name”)
注意Request.Cookies集合(和其他所有Request集合一樣)是唯讀的。 Response.Cookies集合是只寫的,事實上可以存取這個集合中一系列cookie的名稱,而不是它們的值。
遍歷Cookies集合
為了使用Cookies集合更方便,可使用名稱為Haskeys的附加屬性。假如存取的cookie本身也是一個集合,即它是一個多值的cookie,這將傳回True。使用Haskeys屬性,可以遍歷完整的Request.Cookies集合,從而獲得所有cookie的列表及它們的值。
For Each objItem In Request.Cookies
If Request.Cookies(objItem).HasKey Then
'Use another For Each to iterate all subkeys
For Each objItemKey in Request.Cookies(objItem)
Response.Write objItem & “(“ & objItemKey & “) = “_
& Request.Cookies(objItem)(objItemKey) & “<BR>”
Next
Else
'Print out the cookie string as normal
Response.Write objItem & “ = ”& Request.Cookies(objItem) & “<BR>”
End If
Next
這非常類似於前面的從Request.Form集合中提取多個值的複雜程式碼。但這裡可以使用Haskeys屬性來判別每個條目是否為一個集合。而在Form範例裡,必須查詢Request.Form(item_name).Count屬性,這是因為Form集合(和所有的除cookie外的其他集合)成員不可能是真正的集合。 ASP只是做了「幕後」的工作,得到了每個多條目集合的值。
Form和QueryString的差異
了解了存取各種ASP集合的技術以後,需要解決另一個問題是:Form和QueryString集合之間的差異是什麼?假如準備使用ASP,毫無疑問應該清楚這種差異,但需要參考HTTP工作方式來重新認識,並理解它們。
透過HTTP從Web伺服器請求頁面或其他資源,有兩個通用的方法。可使用GET方法直接取得資源,也可使用POST把數值傳給對應資源。 GET方法是預設的,可以看一下本章前面的一個HTTP請求的實例:
7/8/99 10:27:16 Sent GET /Store/Download.asp HTTP/1.1
假如把一個或多個成對的名稱/值附在請求頁面的URL後,就變成請求的查詢字串,且在QueryString集合中提供給ASP頁面。點擊Web頁面、Email訊息或其它文件的超鏈接,或在瀏覽器的網址列中輸入地址並按回車,或點擊瀏覽器中的Links或Favorites按鈕,所有這些都要使用GET方法。
因此,對這些動作中傳遞值給ASP的唯一方法是透過QueryString集合,把值附在URL後面。
出現在Request.QueryString集合中並被存取的值,與前面看到的Form集合實例中的工作方式相同。 URL與查詢字串的結合:
http://mysite.com/process_page.asp?FirstName=Priscilla&LastName=Descartes
可以如下存取在QueryString集合中提供的值:
strFirstName = Request.QueryString(“FirstName”) 'Return “Priscilla”
strLastName = Request.QueryString(“LastName”) 'Return “Descartes”
strRaw = Request.QueryString
'Return “FirstName=Priscilla&LastName=Descartes”
窗體的GET和POST方法
在一個頁面內使用<FORM>段時,可以設定打開的FORM標記的METHOD屬性值為“GET”或“POST”,缺省值為「GET」。假如使用「GET」或省略其屬性,瀏覽器將該值綁定在頁面所有控制項上,成為一個查詢字串,並附在被要求頁面的URL上。
當這個請求到達Web伺服器時,其值由ASP的Request.QueryString集合提供。然而,如果設定METHOD屬性為“POST”,瀏覽器將值包裝進發送伺服器的HTTP標頭中,透過Request.Form集合提供給ASP。
透過來說,可以在所有的HTML窗體中使用POST方法。然而,瀏覽器或伺服器的URL字串長度有一定的限制。因此,附有長的字串可能會引起溢出和某些字串的字元被截斷。同時,查詢字串出現在瀏覽器的網址列和所有的已儲存的連結和收藏夾中。不僅如此,還顯露了通過Web伺服器時在HTTP請求中不想顯示的值,它也可能出現你的伺服器和其他路由伺服器的日誌檔案中。在HTTP請求標頭中的值很少是可見的,且不出現在日誌檔案中。
使用POST方法需要注意的小問題是,當使用者重新下載<FORM>時,窗體的值將不再保留,其值為空且必須重新輸入。然而,當附在URL上時,其值被儲存為一個鏈接,將被保留,因此將出現在所有的URL與字串結合的請求中,這或許是個優點也可能是個缺點,這根據應用而定(有些瀏覽器在用戶端上能夠在一定範圍內自動保留一個頁面上的值)。
另一點是URL與查詢字串的結合體不能包含任何空格或其他非法字符,否則的話,Navigator和一些其他的瀏覽器將出現問題。非法字元是用來分隔URL和查詢字串的部分,例如“/”、“:”、“?”和“&”(IE能夠自動將空格轉換為正確的格式——加號“+”,但其他的非法字元不能處理)
ASP中的cookie的使用
在這一節我們將學習那些提供給ASP程式碼使用的集合、方法和屬性的各種技術。
1) cookie中儲存使用者的細節情況
可以使用cookie來儲存這兩類值:當瀏覽器關閉時我們不想儲存的值(例如使用者的註冊資訊)以及在使用者造訪網站時要保留的值。在每種情況下cookie的值對於來自使用者瀏覽器的每個頁面請求的ASP都是可用的。
然而,要記住的是,cookie只有在對Cookie中的虛擬路徑(path)內的頁面發出請求時,才會發送到伺服器。缺省時,假如path的值在cookie中沒有設置,則其值為建立cookie的頁面的虛擬路徑。要使一個cookie發送到一個網站的所有頁面,需要使用path=「/」。
這裡是個實例,從自訂的Login頁面中,將使用者的註冊資訊存貯在一個cookie中,由於沒有應用有效期,cookie值僅在關閉這個瀏覽器這之前保留:
...
Request.Cookies(“User”)(“UID”) = “<% = Request(“UserName”) %>”
Request.Cookies(“User”)(“PWD”) = “<% = Request(“Password”) %>”
Request.Cookies(“User”).Path = “/adminstuff” 'Only applies to admin pages
……
現在,在使用者從adminstuff目錄或其子目錄請求的每個頁面中,都可以找到這個cookie。如果它不存在,可以將使用者重新導向到註冊頁面:
If (Request.Cookies(“User”)(“UID”) <> “alexhomer”) _
Or (Request.Cookies(“User”)(“PWD”) <> “secret”) Then
Response.Redirect “login.asp?UserName=” & Request.Cookies(“User”)(“UID”)
End If
……
由於把cookie中的使用者名稱放在Response.Redirect的URL查詢字串中,假如在口令輸入時出現錯誤且希望使用者不必重新鍵入使用者名,可以在login.asp頁面中使用它:
<FORM ACTION=”check_user.asp” METHOD=”POST”>
<INPUT TYPE=”TEXT” NAME=”UserName”
VALUE=”<% = Request.QueryString(“UserName”) %>”><P>
<INPUT TYPE=”SUBMIT” VALUE=”LOGIN”>
</FORM>
2) 修改現有的cookie
可以使用ASP修改現有的cookie,但無法只修改cookie中的一個值。當更新一個在Response.Cookies集合中的Cookie時,現有的值將會遺失。我們可以用以下程式碼建立一個cookie,可以使用:
Response.Cookies(“VisitCount”)(“StartDate”) = dtmStart
Response.Cookies(“VisitCount”)(“LastDate”) = Now
Response.Cookies(“VisitCount”)(“Visits”) = CStr(intVisits)
Response.Cookies(“VisitCount”).Path = “/” 'Apply to entire site
Response.Cookies(“VisitCount”).Expires = DateAdd(“m”,3,Now)
假如想要更新Visits和LastDate的值,必須先不需要改變的所有值,然後重寫整個的cookie:
datDtart = Response .Cookies(“VisitCount”)(“StartDate”)
intVisits = Response.Cookies(“VisitCount”)(“Visits”)
Response.Cookies(“VisitCount”)(“StartDate”) = dtmStart
Response.Cookies(“VisitCount”)(“LastDate”) = Now
Response.Cookies(“VisitCount”)(“Visits”) = Cstr(intVisits)
Response.Cookies(“VisitCount”).Path = “/”
Response.Cookies(“VisitCount”).Expires = DateADD(“m”,3,Now + 1)且對於幾乎所有的其他Response方法和屬性,應該在寫入任何內容(即打開<HTML>標記或任何文本或其他的HTML)到回應之前完成這個工作。