- 相關(guān)推薦
ASP3.0高級(jí)編程(三)
訪問和更新Cookies集合Cookies的值比ASP其他集合(例如Form和ServerVariables)的值要復(fù)雜得多。Cookie是一小塊由瀏覽器存貯在客戶端系統(tǒng)上的文本,且隨同每次請(qǐng)求發(fā)往它們應(yīng)用于的域中的服務(wù)器。
ASP使得應(yīng)用cookie較為容易,可以從Request對(duì)象的Cookies集合中獲得所有隨同請(qǐng)求發(fā)出的cookie值,并可創(chuàng)建或修改cookie,通過Response對(duì)象的Cookies集合發(fā)回給用戶。
Cookie包含可用兩種方式構(gòu)造的信息,單值cookie提供其值給代碼是通過一個(gè)一般的類ASP集合。然而,集合的每個(gè)成員可能本身也是一個(gè)集合,包含這種信息的cookie通過稱為多值(multiple-Value)cookie。
創(chuàng)建一個(gè)單值的cookie較為簡單,如下所示:
Response.Cookies(“item-name”) = “item-value”
創(chuàng)建一個(gè)多值的cookie,可以使用如下命令:
Response.Cookies(“item-name”)(“sub-item-name”) = “sub-item-value”
設(shè)置cookie應(yīng)用的域及路徑及其有效期,我們使用:
Response.Cookies(“item-name”).domain = “domain-url”
Response.Cookies(“item-name”).path = “virtual-path”
Response.Cookies(“item-name”).expires = #date#
通常,客戶只在對(duì)創(chuàng)建cookie的目錄中的頁面提出請(qǐng)求時(shí),才將cookie隨請(qǐng)示發(fā)住服務(wù)器。通過指定path屬性,可以指定站點(diǎn)中何處這個(gè)cookie是合法的,并且這個(gè)cookie將隨請(qǐng)求發(fā)送。如果cookie隨對(duì)整個(gè)站點(diǎn)的頁面請(qǐng)求發(fā)送,設(shè)置path為“/”。
假如Expires屬性沒有設(shè)置,關(guān)閉當(dāng)前的瀏覽器實(shí)例時(shí),cookie將被自動(dòng)消除。
注意,我們?cè)谙驗(yàn)g覽器發(fā)送任何輸出時(shí),已經(jīng)創(chuàng)建了cookie。因?yàn),這些cookie是頁面HTTP報(bào)頭的一部分。
在ASP 3.0中,緩沖的缺省狀態(tài)是打開的,且沒有輸出被發(fā)送,除非使用Response.Flush指定做這個(gè)工作或者頁面已到末端。這意味著創(chuàng)建cookie的代碼可以在頁面上的任何位置,直到任何輸出“刷新”(flush)到客戶端前,它都可以被執(zhí)行。
要讀現(xiàn)有的cookie,使用Request.Cookies集合?梢詥为(dú)訪問其中的項(xiàng)目,方法類似于創(chuàng)建它們時(shí)使用的方法。
StrSingleValue = Request.Cookies(“item-name”)
StrSubItemValue = Request.Cookies(“item-name”)(“sub-item-name”)
注意Request.Cookies集合(和所有其他Request集合一樣)是只讀的。Response.Cookies集合是只寫的,事實(shí)上可以訪問這個(gè)集合中一系列cookie的名稱,而不是它們的值。
遍歷Cookies集合
為了使用Cookies集合更加方便,可使用名稱為Haskeys的附加屬性。假如訪問的cookie本身也是個(gè)集合,即它是一個(gè)多值的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集合中提取多個(gè)值的復(fù)雜代碼。但是這里可以使用Haskeys屬性來判別每個(gè)條目是否為一個(gè)集合。而在Form例子里,必須查詢Request.Form(item_name).Count屬性,這是因?yàn)镕orm集合(和所有的除cookie外的其他集合)成員不可能是真正的集合。ASP只是做了“幕后”的工作,得到了每個(gè)多條目集合的值。
Form和QueryString的差異
了解了訪問各種ASP集合的技術(shù)以后,需要解決另一個(gè)問題是:Form和QueryString集合之間的差異是什么?假如準(zhǔn)備使用ASP,毫無疑問應(yīng)該清楚這種差異,但需要參考HTTP工作方式來重新認(rèn)識(shí),理解它們。
通過HTTP從Web服務(wù)器請(qǐng)求頁面或其他資源,有兩個(gè)通用的方法?墒褂肎ET方法直接獲得資源,也可使用POST把值傳給相應(yīng)資源。GET方法是缺省的,可以看一下本章前面的一個(gè)HTTP請(qǐng)求的實(shí)例:
7/8/99 10:27:16 Sent GET /Store/Download.asp HTTP/1.1
假如把一個(gè)或多個(gè)成對(duì)的名稱/值附在請(qǐng)求頁面的URL后,就變成請(qǐng)求的查詢字符串,且在QueryString集合中提供給ASP頁面。單擊Web頁面、Email消息或其它文檔的超鏈接,或在瀏覽器的地址欄中輸入地址并按回車,或單擊瀏覽器中的Links或Favorites按鈕,所有這些都要使用GET方法。
因此,對(duì)這些動(dòng)作中傳遞值給ASP的唯一方法是通過QueryString集合,把值附在URL后。
出現(xiàn)在Request.QueryString集合中并被訪問的值,與前面看到的Form集合實(shí)例中的工作方式相同。URL和查詢字符串的結(jié)合:
http://mysite.com/process_page.asp?FirstName=Priscilla&LastName=Descartes
可以采用如下方式訪問在QueryString集合中提供的值:
strFirstName = Request.QueryString(“Fi
rstName”) ‘Return “Priscilla”
strLastName = Request.QueryString(“LastName”) ‘Return “Descartes”
strRaw = Request.QueryString
‘Return “FirstName=Priscilla&LastName=Descartes”
窗體的GET和POST方法
在一個(gè)頁面內(nèi)使用<FORM>段時(shí),可以設(shè)置打開的FORM標(biāo)記的METHOD屬性值為“GET”或“POST”,缺省值為“GET”。假如使用“GET”或省略其屬性,瀏覽器將該值綁定在頁面所有控件上,成為一個(gè)查詢字符串,且附在被請(qǐng)求頁面的URL上。
當(dāng)這個(gè)請(qǐng)求到達(dá)Web服務(wù)器時(shí),其值由ASP的Request.QueryString集合提供。然而,假如設(shè)置METHOD屬性為“POST”,瀏覽器將值包裝進(jìn)發(fā)送服務(wù)器的HTTP報(bào)頭中,通過Request.Form集合提供給ASP。
通過來說,可以在所有的HTML窗體中使用POST方法。然而,瀏覽器或服務(wù)器的URL字符串長度存在一定的限制。因此,附有長的字符串可能會(huì)引起溢出和某些字符串的字符被截掉。同時(shí),查詢字符串出現(xiàn)在瀏覽器的地址欄和所有的保存的鏈接和收藏夾中。不僅如此,還顯露了通過Web服務(wù)器時(shí)在HTTP請(qǐng)求中不想顯示的值,它也可能出現(xiàn)你的服務(wù)器和其他路由服務(wù)器的日志文件中。在HTTP請(qǐng)求報(bào)頭中的值很少是可見的,并且不出現(xiàn)在日志文件中。
使用POST方法需要注意的小問題是,當(dāng)用戶重新下載<FORM>時(shí),窗體的值將不再保留,其值為空且必須重新輸入。然而,當(dāng)附在URL上時(shí),其值被存儲(chǔ)為一個(gè)鏈接,將被保留,因此將出現(xiàn)在所有的URL與字符串結(jié)合的請(qǐng)求中,這或許是個(gè)優(yōu)點(diǎn)也可能是個(gè)缺點(diǎn),這根據(jù)應(yīng)用而定(一些瀏覽器在客戶端上能夠在一定范圍內(nèi)自動(dòng)保留一個(gè)頁面上的值)。
另一點(diǎn)是URL與查詢字符串的結(jié)合體不能包含任何空格或其他非法字符,否則的話,Navigator和一些其他的瀏覽器將出現(xiàn)問題。非法字符是那些用來分隔URL和查詢字符串的部分,例如“/”、“:”、“?”和“&”(IE能夠自動(dòng)將空格轉(zhuǎn)換為正確的格式——加號(hào)“+”,但其他的非法字符不能處理)。ASP服務(wù)器對(duì)象提供URLEncode方法處理這種變換,以后章節(jié)討論相關(guān)內(nèi)容。
查看Request和Response對(duì)象內(nèi)容
到目前,主要討論了一些理論問題,沒有列舉特別的實(shí)例。因?yàn)橐呀?jīng)討論過的內(nèi)容多數(shù)情況下互相之間是密切相關(guān)的。然而本書為這一章提供了一系列的實(shí)例頁面,說明Request和Response對(duì)象的大多數(shù)屬性。應(yīng)用所講過的實(shí)例,能夠理解這些頁面,并可進(jìn)行相應(yīng)的修改,用它們作為試驗(yàn)實(shí)例。
本章及其他所有章節(jié)的代碼樣例均提供給用戶,可以從Wrox出版社站點(diǎn)下載。
http://webdev.wrox.co.uk/books/2610
http://www.wrox.com/Store/Details.asp?Code=2610
必須首先在Web服務(wù)器的WWWRoot內(nèi)的子目錄下安裝實(shí)例,然后使用瀏覽器訪問Chapter02子目錄,使用:
http://your_server_name_or_IP/subdirectory_name/Chapter02/Default.asp
這里your_server_name_or_IP/subdirectory_name是安裝下載文件的本地路徑。
1、查看Request對(duì)象成員
這提供一個(gè)包含選頁的菜單用來試驗(yàn)Request和Response對(duì)象,首先選擇Using the Request Object,如下圖所示:
下圖顯示一個(gè)HTML窗體的實(shí)例,包含一些預(yù)先設(shè)置好的值,可以按自己的想法編輯這些值,然后點(diǎn)擊“Submit”按鈕。
這將打開一個(gè)頁面,如下圖所示,顯示集合和TotalBytes屬性的全部內(nèi)容。第一屏顯示的是Form、QueryString和Cookies集合。
注意,假如在窗體頁中編輯了HTML控件的值,對(duì)于Cookies集合以及其他的集合,在讀者的計(jì)算機(jī)上的頁面上可能顯示不同的值。
可以從“Form Collection”段中看到窗體上的HTML控件的值如何在ASP的Request.Form集合中表示。也可以用原始的<FORM>頁(名稱為request_form.asp)來試驗(yàn)和檢測,以了解創(chuàng)建窗體的HTML和如何與相應(yīng)值相聯(lián)系。
這個(gè)頁面后面是ClientCertificate集合。這里是空的,因?yàn)榉⻊?wù)器不要求客戶端提供證書。下面是的ServerVariables集合,下圖的屏幕圖顯示的是集合中包含的有用的值。
在本書的后面附錄中可以找到所有ServerVariables集合成員的一個(gè)列表,及其值的說明。然而,可從前面討論的在請(qǐng)求頁面時(shí)從客戶端發(fā)出的HTTP報(bào)頭中見到這些成員。當(dāng)請(qǐng)求收到后,Web服務(wù)器也增加它本身的一些值到集合中,正如上面可以看到的運(yùn)行在IIS 5.0創(chuàng)建的頁面那樣。
1) 頁面是如何工作的
為了創(chuàng)建這個(gè)頁面,使用了本章前面在對(duì)Form集合和如何訪問其值的討論中所看到的完全相同的代碼。例如,遍歷所有的集合(除Request.Cookies外),使用:
For Each objItem In Request.collection_name
Response.Write objItem & “ = “ & Request.collection_name(objItem) & “<BR>”
Next
遍歷Cookies集合,可以使用:
For Each objItem In Request.Cookies
If Request.Cookies(objItem).HasKeys Then
‘Use another For ... Each to iterate all keys of dictionary
For Each objItemKey in Request.Cookies(objItem)
Resonse.Write objItem objItem & “(“ & objItemKey & “) = “_
& Request.Cookies(objItem)(objItemKey) & “<BR>”
Next
Else
‘Print out the cookie string as normal
Response.Write objItem &
amp; “ = “ & Request.Cookies(objItem) & “<BR>”
End If
Next
為獲得TotalBytes屬性,可簡單地使用:
Request.TotalBytes = <% = Request.TotalBytes %><P>
讀者應(yīng)該注意到,在兩個(gè)集合中出現(xiàn)的某些值不是從窗體的HTML控件中直接得到的。QueryString集合包括了兩個(gè)名為chapter和sample的值,如下圖所示:
為在請(qǐng)求中創(chuàng)建這兩個(gè)值,將一個(gè)字符串附在窗體的ACTION屬性的URL上,這是可以接受的。工作方式與附在一個(gè)<A>元素的HREF屬性上相類似。查詢字符的值出現(xiàn)在QueryString集合中,且被POST的窗體控件值出現(xiàn)在Form集合中。
<FORM ACTION=”show_request.asp?chapter=2&sample=The+Request+Object” METHOD=”POST”>
為防止非IE類的瀏覽器出現(xiàn)錯(cuò)誤,必須將查詢字符串中的空格用加號(hào)“+”來代替,讀者將在第4章的Server對(duì)象的URLEncode方法中看到更多這種情況。
2) 創(chuàng)建客戶端的cookie
為了確保至少有些值出現(xiàn)在Request.Cookies集合中,增加一些客戶端腳本代碼到原始的<FORM>頁面request_form.asp。將創(chuàng)建名稱為VisitCount的多值cookie。另一個(gè)cookie是由另一個(gè)頁面創(chuàng)建的,且已經(jīng)存在于瀏覽器中。如下圖所示,讀者可以看到另外的cookie。
這是一段窗體被裝載時(shí)設(shè)置文檔對(duì)象的cookies屬性的客戶端代碼:
<SCRIPT LANGUAGE=”JavaScript”>
<!--
documet.cookie = ’VisitCount=VISITS=3&LASTDATE=6%2F4%2F99+10%3A10%3A13+AM’;
//-->
</SCRIPT>
另外,必須將內(nèi)容進(jìn)行編碼,以便它能被正確地傳送到服務(wù)器(同樣的規(guī)則也適用于將查詢字符串附到URL上)。在第4章中,討論Server對(duì)象的URLEncode方法時(shí),讀者將了解到更多細(xì)節(jié)。
2、查看Response對(duì)象的成員
回到Chapter02實(shí)例的最初的Default.asp頁面,這次選擇“Using the Response Object”鏈接,這個(gè)頁面顯示的是Response對(duì)象的集合和屬性的內(nèi)容,且提供到所有Response對(duì)象方法的鏈接。
下圖是使用瀏覽器Netsape Communicator 4.61的屏幕,用來證明使用的是純服務(wù)器端和跨平臺(tái)兼容技術(shù)。需要注意的是Cookies集合是為Response對(duì)象而建立的,僅顯示cookie的名稱而不顯示其值。瀏覽該頁時(shí),可能得不到cookie或得到與這個(gè)頁面不同的cookie。
(由于豆豆沒有安裝Netsape Communicator 4.61,仍用IE5.5顯示,并無什么區(qū)別)
各種Response屬性說明了將要用來創(chuàng)建HTTP報(bào)頭的一些信息。HTTP報(bào)頭頁面的其他部分(HTML和文本內(nèi)容)被發(fā)往到客戶端。這些屬性中的一些以及所有的Response對(duì)象的方法均有鏈接,允許讀者打開另一個(gè)頁面來顯示其使用情況。我們稍后再回到這些頁面。
頁面中的屬性是通過讀取相應(yīng)的屬性并插入到頁面中創(chuàng)建的。由于這些是動(dòng)態(tài)鏈接,通過<A>元素來選擇。
<A HREF = ”headers/expiretet_form.asp”>Response.CacheControl</A>
= <% = Resposne.CacheControl %><BR>
鏈接到每個(gè)方法是通過<A>鏈接元素,頁面中唯一復(fù)雜的部分是Response.Cookies集合。通過只能訪問cookie,讀取Request.Cookies集合中的值。當(dāng)訪問Response.Cookie集合時(shí),必須在發(fā)送任何輸出到客戶端之前結(jié)束對(duì)它的所有引用。因此在頁面的上部,通過遍歷集合創(chuàng)建頁面的HTML放在一個(gè)局部字符串變量中。
StrCookies = “”
‘We can only read the key names and not the values because
‘the Response.Cookies collection is ‘write only’
For Each objItem In Response.Cookies
If Response.Cookies(objItem).HasKeys Then
‘Use another For Each to iterate all subkeys
For Each objItemKey in Response.Cookies(objItem)
StrCookies = strCookies & objItem & “(“ &objItemKey & “)<BR>”
Next
Else
‘print out the cookie as normal
strCookies = strCookies & objItem & “<BR>”
End If
Next
然后在頁面的適當(dāng)點(diǎn)上插入結(jié)果。
<P><DIV CLASS=”subhead”>The Response.Cookies Collection</DIV>
<I><A HREF=”cookies/setcookies.asp”>Response.Cookies</A>
is a write-only collection so the values cannot be displayed</I><BR>
<% = strCookies %>
ASP中的cookie的使用
在前面所看到頁面中,一些集合、屬性和方法已經(jīng)鏈接到其他的頁面,用來顯示Request和Response對(duì)象的各個(gè)特性細(xì)節(jié),我們將在本章的其余的部分研究這些內(nèi)容,我們將學(xué)習(xí)那些提供給ASP代碼使用的集合、方法和屬性的各種技術(shù)。
在本章前面已經(jīng)看到了如何使用Request.Cookies和Resp
onse.Cookies集合來創(chuàng)建和閱讀cookie,點(diǎn)擊上面兩個(gè)頁面中的任一個(gè)的“Cookies”鏈接時(shí),這個(gè)頁面包含一些設(shè)置了三個(gè)cookie的值的ASP代碼,且在頁面上顯示被執(zhí)行的代碼,如下圖所示:
點(diǎn)擊“Show Cookies”的鏈接時(shí),cookie的內(nèi)容就顯示出來了。這是通過遍歷Request.Cookies集合而得到的,這與在上一頁所用的方式完全相同,如下圖所示:
這個(gè)屏幕圖顯示的是運(yùn)行前面看到的設(shè)置cookie值的代碼的結(jié)果?赡軙(huì)看到其他已經(jīng)存貯在計(jì)算機(jī)系統(tǒng)里的cookie。然而,假如現(xiàn)在關(guān)閉瀏覽器然后重新打開瀏覽器,然后運(yùn)行顯示cookie的頁面,除了TimedCookie外,所有的cookie都不見了,這是由于只有這個(gè)TimedCookie具有有效期的設(shè)置,其他的在瀏覽器關(guān)閉時(shí),自動(dòng)消失了。
1) cookie中存儲(chǔ)用戶的細(xì)節(jié)情況
可以使用cookie來存儲(chǔ)這兩類值:當(dāng)瀏覽器關(guān)閉時(shí)我們不想保存的值(例如用戶的注冊(cè)信息)以及在用戶訪問站點(diǎn)時(shí)要保留的值。在每種情況下cookie的值對(duì)于來自用戶瀏覽器的每個(gè)頁面請(qǐng)求的ASP都是可用的。
然而,需要記住的是,cookie只有在對(duì)Cookie中的虛擬路徑(path)內(nèi)的頁面發(fā)出請(qǐng)求時(shí),才會(huì)發(fā)往服務(wù)器。缺省時(shí),假如path的值在cookie中沒有設(shè)置,則其值為創(chuàng)建cookie的頁面的虛擬路徑。為使一個(gè)cookie發(fā)往一個(gè)站點(diǎn)的所有頁面,需要使用path=“/”。
這里是個(gè)實(shí)例,從自定義的Login頁面中,將用戶的注冊(cè)信息存貯在一個(gè)cookie中,由于沒有應(yīng)用有效期,cookie值僅在關(guān)閉這個(gè)瀏覽器這前保留:
...
Request.Cookies(“User”)(“UID”) = “<% = Request(“UserName”) %>”
Request.Cookies(“User”)(“PWD”) = “<% = Request(“Password”) %>”
Request.Cookies(“User”).Path = “/adminstuff” ‘Only applies to admin pages
...
現(xiàn)在,在用戶從adminstuff目錄或其子目錄請(qǐng)求的每個(gè)頁面中,都可以找到這個(gè)cookie。假如它不存在,可以將用戶重定向到注冊(cè)頁面:
If (Request.Cookies(“User”)(“UID”) <> “alexhomer”) _
Or (Request.Cookies(“User”)(“PWD”) <> “secret”) Then
Response.Redirect “l(fā)ogin.asp?UserName=” & Request.Cookies(“User”)(“UID”)
End If
...
由于把cookie中的用戶名放在Response.Redirect的URL查詢字符串中,假如在口令輸入時(shí)出現(xiàn)錯(cuò)誤且希望用戶不必重新鍵入用戶名,可以在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) 修改現(xiàn)有的cookie
可以使用ASP修改現(xiàn)有的cookie,但不能只修改cookie中的一個(gè)值。當(dāng)更新一個(gè)在Response.Cookies集合中的Cookie時(shí),現(xiàn)有的值將丟失。我們可以用如下代碼創(chuàng)建一個(gè)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的值,必須先不需改變的所有值,然后重寫整個(gè)的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)且對(duì)于幾乎所有的其他Response方法和屬性,應(yīng)該在寫入任何內(nèi)容(即打開<HTML>標(biāo)記或任何文本或其他的HTML)到響應(yīng)之前完成這個(gè)工作。
【ASP3.0高級(jí)編程三】相關(guān)文章:
ASP3.0高級(jí)編程(四)08-06
ASP 3.0高級(jí)編程(三)08-06
ASP 3.0高級(jí)編程(二)08-06
ASP 3.0高級(jí)編程(四)08-06
ASP 3.0高級(jí)編程(一)08-06
編程的心得09-13
Delphi拖放編程08-06
編程的心得最新09-19
系統(tǒng)托盤的編程08-19