明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

ASP.NET中Cookie編程的基礎(chǔ)知識(4)

[摘要]控制 Cookie 有效范圍  默認情況下,一個站點的全部 Cookie 都一起保存在客戶機上,而且所有這些 Cookie 都會隨著對該站點發(fā)送的請求一起發(fā)送到服務(wù)器,也就是說,站點的每個頁面都能得到該站點的所有 Cookie。但有時候,您可能希望 Cookie 更具有針對性,這時,您可以通過兩種...
控制 Cookie 有效范圍

  默認情況下,一個站點的全部 Cookie 都一起保存在客戶機上,而且所有這些 Cookie 都會隨著對該站點發(fā)送的請求一起發(fā)送到服務(wù)器,也就是說,站點的每個頁面都能得到該站點的所有 Cookie。但有時候,您可能希望 Cookie 更具有針對性,這時,您可以通過兩種方法設(shè)置 Cookie 的有效范圍:

  把 Cookie 的有效范圍限制在服務(wù)器上的一個文件夾中,實際上這樣就將 Cookie 限制到站點上的某個應(yīng)用程序。

  把有效范圍設(shè)置為某個域,從而允許您指定域中的哪些子域可以訪問 Cookie。

  將 Cookie 限制到某個文件夾或應(yīng)用程序

  要將 Cookie 限制到服務(wù)器上的某個文件夾,請按如下方法設(shè)置 Cookie 的 Path 屬性:

Dim appCookie As New HttpCookie("AppCookie")
appCookie.Value = "written " & Now.ToString
appCookie.Expires = Now.AddDays(1)
appCookie.Path = "/Application1"
Response.Cookies.Add(appCookie)

  當然,您也可以通過直接設(shè)置 Response.Cookies 來編寫 Cookie,如前文所述。

  路徑可以是站點根目錄下的物理路徑,也可以是虛擬根目錄。這樣一來,Cookie 就只能用于 Application1 文件夾或虛擬根目錄中的頁面。例如,如果您的站點名為 www.contoso.com,則前面示例中生成的 Cookie 就只能用于路徑為 http://www.contoso.com/Application1/ 的頁面以及該文件夾下的所有頁面,而不適用于其他應(yīng)用程序中的頁面,如 http://www.contoso.com/Application2/http://www.contoso.com/ 下的頁面。

  提示:通過對 Internet Explorer 和 Mozilla 瀏覽器進行測試發(fā)現(xiàn),此處使用的路徑是區(qū)分大小寫的。一般而言,Windows 服務(wù)器上的 URL 不區(qū)分大小寫,但這種情況例外。您無法控制用戶如何在瀏覽器中輸入 URL,但是,如果您的應(yīng)用程序依賴于與特定路徑相關(guān)的 Cookie,則請確保您所創(chuàng)建的所有超鏈接中的 URL 與 Path 屬性值的大小寫相匹配。

  將 Cookie 的有效范圍限制到域

  默認情況下,Cookie 與特定的域相關(guān)聯(lián)。例如,如果您的站點是 www.contoso.com,那么當用戶向該站點請求頁面時,您編寫的 Cookie 就被發(fā)送到服務(wù)器。(有特定路徑值的 Cookie 除外,我在上一節(jié)剛剛解釋過。) 如果您的站點有子域(例如 contoso.com、sales.contoso.com 和 support.contoso.com),就可以把 Cookie 同特定的子域相關(guān)聯(lián)。為此,需要設(shè)置 Cookie 的 Domain 屬性,如下所示:

Response.Cookies("domain").Value = DateTime.Now.ToString
Response.Cookies("domain").Expires = DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain = "support.contoso.com"

  如果按照這種方式設(shè)置域,則 Cookie 只能用于指定子域中的頁面。

  您也可以利用 Domain 屬性來創(chuàng)建可在多個子域中共享的 Cookie。例如,對域進行如下設(shè)置:

Response.Cookies("domain").Value = DateTime.Now.ToString
Response.Cookies("domain").Expires = DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain = "contoso.com"

  這樣,該 Cookie 就可用于主域、sales.contoso.com 和 support.contoso.com。

  讀取 Cookie

  當瀏覽器向服務(wù)器發(fā)送請求時,該服務(wù)器的 Cookie 會與請求一起發(fā)送。在 ASP.NET 應(yīng)用程序中,您可以使用 Request 對象來讀取 Cookie。Request 對象的結(jié)構(gòu)與 Response 對象的結(jié)構(gòu)基本相同,所以從 Request 對象中讀取 Cookie 的方法與向 Response 對象中寫入 Cookie 的方法非常類似。以下示例顯示了兩種方法,目的都是獲取名為“username”的 Cookie 的值并將值顯示在 Label 控件中:

If Not Request.Cookies("userName") Is Nothing Then
Label1.Text = Server.HtmlEncode(Request.Cookies("userName").Value)
End If

If Not Request.Cookies("userName") Is Nothing Then
Dim aCookie As HttpCookie = Request.Cookies("userName")
Label1.Text = Server.HtmlEncode(aCookie.Value)
End If 

  在獲取 Cookie 的值之前,應(yīng)該確保該 Cookie 確實存在。否則,您將得到一個 System.NullReferenceException(英文)異常。還需要注意的是,在頁面中顯示 Cookie 的內(nèi)容之前,我調(diào)用了 HttpServerUtility.HtmlEncode(英文)方法對 Cookie 的內(nèi)容進行編碼。之所以這樣做,是因為我要顯示 Cookie 的內(nèi)容(一般您不會這樣做)而且要確保沒有任何惡意用戶在 Cookie 中添加了可執(zhí)行腳本。有關(guān) Cookie 安全性的詳細信息,請參閱 Cookie 和安全性。

  注意:由于不同的瀏覽器保存 Cookie 的方式也不同,所以同一臺計算機上的不同瀏覽器不一定能夠相互讀取各自的 Cookie。例如,如果使用 Internet Explorer 測試一個頁面,然后再使用其他瀏覽器進行測試,那么后者就不會找到 Internet Explorer 保存的 Cookie。當然,大多數(shù)人一般都是使用同一種瀏覽器進行 Web 交互的,因此在大多數(shù)情況下不會出現(xiàn)問題。但有時還是會遇到問題,比如您要測試應(yīng)用程序?qū)g覽器的兼容性。

  讀取 Cookie 中子鍵值的方法與設(shè)置該值的方法類似。以下是獲取子鍵值的一種方法:

If Not Request.Cookies("userInfo") Is Nothing Then
Label1.Text = _
Server.HtmlEncode(Request.Cookies("userInfo")("userName"))
Label2.text = _
Server.HtmlEncode(Request.Cookies("userInfo")("lastVisit"))
End If

  在上面的示例中,我獲取的是子鍵“l(fā)astVist”的值,在此前的討論中我把該值設(shè)置為 DateTime 值的字符串表示形式。請記住,Cookie 是用字符串的形式保存值的,所以要將 lastVisit 值用作日期,就必須對其進行轉(zhuǎn)換:

Dim dt As DateTime
dt = CDate(Request.Cookies("userInfo")("lastVisit"))

  Cookie 中子鍵的類型是 NameValueCollection(英文)類型的集合。因此,另一種獲取單個子鍵的方法是先獲取子鍵集合,然后按名稱提取子鍵的值,如下所示:

If Not Request.Cookies("userInfo") Is Nothing Then
Dim UserInfoCookieCollection As _
System.Collections.Specialized.NameValueCollection
UserInfoCookieCollection = Request.Cookies("userInfo").Values
Label1.Text = Server.HtmlEncode(UserInfoCookieCollection("userName"))
Label2.Text = Server.HtmlEncode(UserInfoCookieCollection("lastVisit"))
End If

  就像設(shè)置 Cookie 一樣,使用哪種方法讀取 Cookie 也由您自己決定。

什么是有效期?

  您可以讀取 Cookie 的名稱和值,除此以外,需要了解的有關(guān) Cookie 的信息并不是很多。雖然您可以獲取 Domain 和 Path 屬性,但是這些屬性的用途很有限。例如,您可以讀取 Domain 屬性,但如果您的頁面與 Cookie 不在相同的域,您根本就不會在頁面的位置接收到該 Cookie。

  您無法讀取的是 Cookie 的過期日期和時間。事實上,當瀏覽器向服務(wù)器發(fā)送 Cookie 信息時,瀏覽器并未將過期信息包括在內(nèi)。您可以讀取 Expires 屬性,但總是返回為零的日期/時間值。

  在前面的編寫 Cookie 一節(jié)中,我已經(jīng)講過,是瀏覽器負責管理 Cookie 的,Expires 屬性就很好地印證了這一點。Expires 屬性的主要作用是幫助瀏覽器執(zhí)行有關(guān) Cookie 保存的日常管理。從服務(wù)器的角度來看,Cookie 要么存在要么不存在,所以對服務(wù)器而言,有效期并不是有用的信息。所以,瀏覽器在發(fā)送 Cookie 時并不提供此信息。如果您需要 Cookie 的過期日期,就必須重新設(shè)置,關(guān)于這一點我將在修改和刪除 Cookie 中介紹。

  更確切地說,您可以在向瀏覽器發(fā)送 Cookie 之前讀取已在 Response 對象中設(shè)置的 Expires 屬性,但您無法從返回的 Request 對象中獲取有效期信息。