ASP.NET Cookie 操作實現

來源:互聯網
上載者:User

ASP.NET Cookie 概述

  Cookie 提供了一種在 Web 應用程式中儲存使用者特定資訊的方法。例如,當使用者訪問您的網站時,您可以使用 Cookie 儲存使用者喜好設定或其他資訊。當該使用者再次訪問您的網站時,應用程式便可以檢索以前儲存的資訊。

什麼是 Cookie?
Cookie 是一小段文本資訊,伴隨著使用者請求和頁面在 Web 服務器和瀏覽器之間傳遞。Cookie 包含每次使用者訪問網站時 Web 應用程式都可以讀取的資訊。

例如,如果在使用者請求網站中的頁面時應用程式發送給該使用者的不僅僅是一個頁面,還有一個包含日期和時間的 Cookie,使用者的瀏覽器在獲得頁面的同時還獲得了該 Cookie,並將它儲存在使用者硬碟上的某個檔案夾中。

以後,如果該使用者再次請求您網站中的頁面,當該使用者輸入 URL 時,瀏覽器便會在本地硬碟上尋找與該 URL 關聯的 Cookie。如果該 Cookie 存在,瀏覽器便將該 Cookie 與頁請求一起發送到您的網站。然後,應用程式便可以確定該使用者上次訪問網站的日期和時間。您可以使用這些資訊向使用者顯示一條訊息,也可以檢查到期日。

Cookie 與網站關聯,而不是與特定的頁面關聯。因此,無論使用者請求網站中的哪一個頁面,瀏覽器和伺服器都將交換 Cookie 資訊。使用者訪問不同網站時,各個網站都可能會向使用者的瀏覽器發送一個 Cookie;瀏覽器會分別儲存所有 Cookie。

Cookie 協助網站儲存有關訪問者的資訊。一般來說,Cookie 是一種保持 Web 應用程式連續性(即執行狀態管理)的方法。除短暫的實際交換資訊的時間外,瀏覽器和 Web 服務器間都是中斷連線的。對於使用者向 Web 服務器發出的每個請求,Web 服務器都會單獨處理。但是在很多情況下,Web 服務器在使用者請求頁時識別出使用者會十分有用。例如,購物網站上的 Web 服務器跟蹤每位購物者,這樣網站就可以管理購物車和其他的使用者特定資訊。因此,Cookie 可以作為一種名片,提供相關的標識資訊輔助應用程式確定如何繼續執行。

使用 Cookie 能夠達到多種目的,所有這些目的都是為了協助網站記住使用者。例如,一個實施民意測驗的網站可以簡單地將 Cookie 作為一個 Boolean 值,用它來指示使用者的瀏覽器是否已參與了投票,這樣使用者便無法進行第二次投票。要求使用者登入的網站則可以通過 Cookie 來記錄使用者已經登入,這樣使用者就不必每次都輸入憑據。

Cookie 的限制
大多數瀏覽器支援最大為 4096 位元組的 Cookie。由於這限制了 Cookie 的大小,最好用 Cookie 來儲存少量資料,或者儲存使用者識別碼 之類的標識符。使用者識別碼 隨後便可用於標識使用者,以及從資料庫或其他資料來源中讀取使用者資訊。(有關儲存使用者資訊安全建議的資訊,請參見下面的“Cookie 和安全性”一節。)

瀏覽器還限制網站可以在使用者電腦上儲存的 Cookie 的數量。大多數瀏覽器只允許每個網站儲存 20 個 Cookie;如果試圖儲存更多 Cookie,則最舊的 Cookie 便會被丟棄。有些瀏覽器還會對它們將接受的來自所有網站的 Cookie 總數作出絕對限制,通常為 300 個。

您可能遇到的 Cookie 限制是使用者可以將其瀏覽器設定為拒絕接受 Cookie。如果定義一個 P3P 隱私權原則,並將其放置在網站的根目錄中,則更多的瀏覽器將接受您網站的 Cookie。但是,您可能會不得不完全放棄 Cookie,而通過其他機制來儲存使用者特定的資訊。儲存使用者資訊的常用方法是工作階段狀態,但工作階段狀態依賴於 Cookie,這一點在後面的“Cookie 和工作階段狀態”一節中說明。

注意
有關 Web 應用程式中的狀態管理和用於儲存資訊的選項的更多資訊,請參見 ASP.NET 狀態管理概述 和 ASP.NET 狀態管理建議。

雖然 Cookie 在應用程式中非常有用,但應用程式不應依賴於能夠儲存 Cookie。不要使用 Cookie 支援關鍵功能。如果應用程式必須依賴於 Cookie,則可以通過測試確定瀏覽器是否將接受 Cookie。請參見本主題後面的“檢查瀏覽器是否接受 Cookie”一節。

編寫 Cookie
瀏覽器負責系統管理使用者系統上的 Cookie。Cookie 通過 HttpResponse 對象發送到瀏覽器,該對象公開稱為 Cookies 的集合。可以將 HttpResponse 對象作為 Page 類的 Response 屬性來訪問。要發送給瀏覽器的所有 Cookie 都必須添加到此集合中。建立 Cookie 時,需要指定 Name 和 Value。每個 Cookie 必須有一個唯一的名稱,以便以後從瀏覽器讀取 Cookie 時可以識別它。由於 Cookie 按名稱儲存,因此用相同的名稱命名兩個 Cookie 會導致其中一個 Cookie 被覆蓋。

還可以設定 Cookie 的到期日和時間。使用者訪問編寫 Cookie 的網站時,瀏覽器將刪除到期的 Cookie。只要應用程式認為 Cookie 值有效,就應將 Cookie 的有效期間設定為這一段時間。對於永不到期的 Cookie,可將到期日設定為從現在起 50 年。

注意
使用者可隨時清除其電腦上的 Cookie。即便儲存的 Cookie 距到期日還有很長時間,但使用者還是可以決定刪除所有 Cookie,清除 Cookie 中儲存的所有設定。

如果沒有設定 Cookie 的有效期間,仍會建立 Cookie,但不會將其儲存在使用者的硬碟上。而會將 Cookie 作為使用者會話資訊的一部分進行維護。當使用者關閉瀏覽器時,Cookie 便會被丟棄。這種非永續性 Cookie 很適合用來儲存只需短時間儲存的資訊,或者儲存由於安全原因不應該寫入用戶端電腦上的磁碟的資訊。例如,如果使用者在使用一台公用電腦,而您不希望將 Cookie 寫入該電腦的磁碟中,這時就可以使用非永續性 Cookie。

可以通過多種方法將 Cookie 添加到 Cookies 集合中。下面的樣本示範兩種編寫 Cookie 的方法:

複製代碼 代碼如下:Response.Cookies["userName"].Value = "patrick";
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(1);

HttpCookie aCookie = new HttpCookie("lastVisit");
aCookie.Value = DateTime.Now.ToString();
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);

此樣本向 Cookies 集合添加兩個 Cookie,一個名為 userName,另一個名為 lastVisit。對於第一個 Cookie,Cookies 集合的值是直接設定的。可以通過這種方式向集合添加值,因為 Cookies 是從 NameObjectCollectionBase 類型的專用集合派生的。

對於第二個 Cookie,代碼建立了一個 HttpCookie 類型的對象執行個體,設定其屬性,然後通過 Add 方法將其添加到 Cookies 集合。在執行個體化 HttpCookie 對象時,必須將該 Cookie 的名稱作為建構函式的一部分進行傳遞。

這兩個樣本都完成了同一任務,即向瀏覽器寫入一個 Cookie。在這兩種方法中,有效期間值必須為 DateTime 類型。但是,lastVisited 值也是日期時間值。因為所有 Cookie 值都儲存為字串,因此,必須將日期時間值轉換為 String。

多值 Cookie
可以在 Cookie 中儲存一個值,如使用者名稱和上次訪問時間。也可以在一個 Cookie 中儲存多個成對的名稱和數值。成對的名稱和數值稱為子鍵。(子鍵布局類似於 URL 中的查詢字串。)例如,不要建立兩個名為 userName 和 lastVisit 的單獨 Cookie,而可以建立一個名為 userInfo 的 Cookie,其中包含兩個子鍵 userName 和 lastVisit。

您可能會出於多種原因來使用子鍵。首先,將相關或類似的資訊放在一個 Cookie 中很方便。此外,由於所有資訊都在一個 Cookie 中,所以諸如有效期間之類的 Cookie 屬性就適用於所有資訊。(反之,如果要為不同類型的資訊指定不同的到期日,就應該把資訊儲存在單獨的 Cookie 中。)

帶有子鍵的 Cookie 還可協助您限制 Cookie 檔案的大小。正如前面“Cookie 的限制”一節中所提到的,Cookie 通常限制為 4096 位元組,並且每個網站最多可儲存 20 個 Cookie。使用帶子鍵的單個 Cookie,使用的 Cookie 數就不會超過分配給網站的 20 個的限制。此外,一個 Cookie 會佔用大約 50 個字元的系統開銷(用於儲存有效期間資訊等),再加上其中儲存的值的長度,其總和接近 4096 位元組的限制。如果儲存五個子鍵而不是五個單獨的 Cookie,便可節省單獨 Cookie 的系統開銷,節省大約 200 位元組。

若要建立帶子鍵的 Cookie,您可以使用編寫單個 Cookie 的各種文法。下面的樣本示範用於編寫同一 Cookie 的兩種方法,其中的每個 Cookie 都帶有兩個子鍵:

複製代碼 代碼如下:Response.Cookies["userInfo"]["userName"] = "patrick";
Response.Cookies["userInfo"]["lastVisit"] = DateTime.Now.ToString();
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(1);

HttpCookie aCookie = new HttpCookie("userInfo");
aCookie.Values["userName"] = "patrick";
aCookie.Values["lastVisit"] = DateTime.Now.ToString();
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);

控制 Cookie 的範圍
預設情況下,一個網站的全部 Cookie 都一起儲存在用戶端上,而且所有 Cookie 都會隨著對該網站發送的任何請求一起發送到伺服器。也就是說,一個網站中的每個頁面都能獲得該網站的所有 Cookie。但是,可以通過兩種方式設定 Cookie 的範圍:

將 Cookie 的範圍限制到伺服器上的某個檔案夾,這允許您將 Cookie 限制到網站上的某個應用程式。

將範圍設定為某個域,這允許您指定域中的哪些子域可以訪問 Cookie。

將 Cookie 限制到某個檔案夾或應用程式
若要將 Cookie 限制到伺服器上的某個檔案夾,請按下面的樣本設定 Cookie 的 Path 屬性:

複製代碼 代碼如下:HttpCookie appCookie = new HttpCookie("AppCookie");
appCookie.Value = "written " + DateTime.Now.ToString();
appCookie.Expires = DateTime.Now.AddDays(1);
appCookie.Path = "/Application1";
Response.Cookies.Add(appCookie);

注意
還可以通過將 Cookie 直接添加到 Cookies 集合的方式來編寫 Cookie,如先前的樣本所示。

路徑可以是網站根目錄下的實體路徑,也可以是虛擬根目錄。所產生的效果是 Cookie 只能用於 Application1 檔案夾或虛擬根目錄中的頁面。例如,如果您的網站名稱為 http://www.contoso.com/,則在前面樣本中建立的 Cookie 將只能用於路徑為 http://www.contoso.com/Application1/ 的頁面以及該檔案夾下的所有頁面。但是,Cookie 將不能用於其他應用程式中的頁面,如 http://www.contoso.com/Application2/ 或 http://www.contoso.com/ 中的頁面。

注意
在某些瀏覽器中,路徑區分大小寫。您無法控制使用者如何在其瀏覽器中鍵入 URL,但如果應用程式依賴於與特定路徑相關的 Cookie,請確保您建立的所有超連結中的 URL 與 Path 屬性值的大小寫相匹配。

限制 Cookie 的域範圍
預設情況下,Cookie 與特定域關聯。例如,如果您的網站是 http://www.contoso.com/,那麼當使用者向該網站請求任何頁時,您編寫的 Cookie 就會被發送到伺服器。(這可能不包括帶有特定路徑值的 Cookie。)如果網站具有子域(例如,contoso.com、sales.contoso.com 和 support.contoso.com),則可以將 Cookie 與特定的子域關聯。若要執行此操作,請設定 Cookie 的 Domain 屬性,如此樣本所示:

Response.Cookies["domain"].Value = DateTime.Now.ToString();
Response.Cookies["domain"].Expires = DateTime.Now.AddDays(1);
Response.Cookies["domain"].Domain = "support.contoso.com";
當以此方式設定域時,Cookie 將僅可用於指定的子域中的頁面。還可以使用 Domain 屬性建立可在多個子域間共用的 Cookie,如下面的樣本所示:

複製代碼 代碼如下: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
瀏覽器向伺服器發出請求時,會隨請求一起發送該伺服器的 Cookie。在 ASP.NET 應用程式中,可以使用 HttpRequest 對象讀取 Cookie,該對象可用作 Page 類的 Request 屬性使用。HttpRequest 對象的結構與 HttpResponse 對象的結構基本相同,因此,可以從 HttpRequest 對象中讀取 Cookie,並且讀取方式與將 Cookie 寫入 HttpResponse 對象的方式基本相同。下面的程式碼範例示範兩種方法,通過這兩種方法可擷取名為 username 的 Cookie 的值,並將其值顯示在 Label 控制項中:

複製代碼 代碼如下:if(Request.Cookies["userName"] != null)
Label1.Text = Server.HtmlEncode(Request.Cookies["userName"].Value);

if(Request.Cookies["userName"] != null)
{
HttpCookie aCookie = Request.Cookies["userName"];
Label1.Text = Server.HtmlEncode(aCookie.Value);
}

在嘗試擷取 Cookie 的值之前,應確保該 Cookie 存在;如果該 Cookie 不存在,將會收到 NullReferenceException 異常。還請注意在頁面中顯示 Cookie 的內容前,先調用 HtmlEncode 方法對 Cookie 的內容進行編碼。這樣可以確保惡意使用者沒有向 Cookie 中添加可執行指令碼。有關 Cookie 安全性的更多資訊,請參見“Cookie 和安全性”一節。

注意
由於不同的瀏覽器儲存 Cookie 的方式不同,因此,同一電腦上的不同瀏覽器沒有必要能夠讀取彼此的 Cookie。例如,如果使用 Internet Explorer 測試一個頁面,然後再使用其他瀏覽器進行測試,那麼後者將不會找到 Internet Explorer 儲存的 Cookie。

讀取 Cookie 中子索引值的方法與設定該值的方法類似。下面的程式碼範例示範擷取子索引值的一種方法:

複製代碼 代碼如下:if(Request.Cookies["userInfo"] != null)
{
Label1.Text =
Server.HtmlEncode(Request.Cookies["userInfo"]["userName"]);

Label2.Text =
Server.HtmlEncode(Request.Cookies["userInfo"]["lastVisit"]);
}

在上面的樣本中,代碼讀取子鍵 lastVisit 的值,該值先前被設定為字串表示形式的 DateTime 值。Cookie 將值儲存為字串,因此,如果要將 lastVisit 值作為日期使用,必須將其轉換為適當的類型,如此樣本所示:

DateTime dt;
dt = DateTime.Parse(Request.Cookies["userInfo"]["lastVisit"]);

Cookie 中的子鍵被類型化為 NameValueCollection 類型的集合。因此,擷取單個子鍵的另一種方法是擷取子鍵集合,然後再按名稱提取子索引值,如下面的樣本所示:

複製代碼 代碼如下:if(Request.Cookies["userInfo"] != null)
{
System.Collections.Specialized.NameValueCollection
UserInfoCookieCollection;

UserInfoCookieCollection = Request.Cookies["userInfo"].Values;
Label1.Text =
Server.HtmlEncode(UserInfoCookieCollection["userName"]);
Label2.Text =
Server.HtmlEncode(UserInfoCookieCollection["lastVisit"]);
}

更改 Cookie 的到期日
瀏覽器負責管理 Cookie,而 Cookie 的到期時間和日期可協助瀏覽器管理 Cookie 的儲存。因此,雖然可以讀取 Cookie 的名稱和值,但無法讀取 Cookie 的到期日和時間。當瀏覽器向伺服器發送 Cookie 資訊時,並不包括有效期間資訊。(Cookie 的 Expires 屬性始終傳回值為 0 的日期時間值。)如果您擔心 Cookie 的到期日,必須重新設定該 Cookie,該過程在“修改和刪除 Cookie”一節中介紹。

注意
可以在向瀏覽器發送 Cookie 之前讀取已在 HttpResponse 對象中設定的 Cookie 的 Expires 屬性。但是,您無法從返回的 HttpRequest 對象中擷取有效期間。

讀取 Cookie 集合
有時,您可能需要讀取可供頁面使用的所有 Cookie。若要讀取可供頁面使用的所有 Cookie 的名稱和值,可以使用如下代碼依次通過 Cookies 集合。

複製代碼 代碼如下:System.Text.StringBuilder output = new System.Text.StringBuilder();
HttpCookie aCookie;
for(int i=0; i<Request.Cookies.Count; i++)
{
aCookie = Request.Cookies[i];
output.Append("Cookie name = " + Server.HtmlEncode(aCookie.Name)
+ "<br />");
output.Append("Cookie value = " + Server.HtmlEncode(aCookie.Value)
+ "<br /><br />");
}
Label1.Text = output.ToString();

注意
在運行此代碼時,可能會看到一個名為 ASP.NET_SessionId 的 Cookie。ASP.NET 使用該 Cookie 來儲存您的會話的唯一識別碼。工作階段 Cookie 不會儲存在您的硬碟上。有關工作階段 Cookie 的更多資訊,請參見本主題後面的“Cookie 和工作階段狀態”一節。

上面的樣本有一個限制:如果 Cookie 有子鍵,則會以一個名稱/值字串來顯示子鍵。可以讀取 Cookie 的 HasKeys 屬性,以確定 Cookie 是否有子鍵。如果有,則可以讀取子鍵集合以擷取各個子鍵名稱和值。可以通過索引值直接從 Values 集合中讀取子索引值。相應的子鍵名稱可在 Values 集合的 AllKeys 成員中獲得,該成員將返回一個字串數組。還可以使用 Values 集合的 Keys 成員。但是,首次訪問 AllKeys 屬性時,該屬性會被緩衝。相比之下,每次訪問 Keys 屬性時,該屬性都產生一個數組。因此在同一頁請求的上下文內,在隨後訪問時,AllKeys 屬性要快得多。

下面的樣本示範對前一樣本的修改。該樣本使用 HasKeys 屬性來測試是否存在子鍵,如果檢測到子鍵,便從 Values 集合擷取子鍵:

複製代碼 代碼如下:for(int i=0; i<Request.Cookies.Count; i++)
{
aCookie = Request.Cookies[i];
output.Append("Name = " + aCookie.Name + "<br />");
if(aCookie.HasKeys)
{
for(int j=0; j<aCookie.Values.Count; j++)
{
subkeyName = Server.HtmlEncode(aCookie.Values.AllKeys[j]);
subkeyValue = Server.HtmlEncode(aCookie.Values[j]);
output.Append("Subkey name = " + subkeyName + "<br />");
output.Append("Subkey value = " + subkeyValue +
"<br /><br />");
}
}
else
{
output.Append("Value = " + Server.HtmlEncode(aCookie.Value) +
"<br /><br />");
}
}
Label1.Text = output.ToString();

或者,可將子鍵作為 NameValueCollection 對象提取,如下面的樣本所示:

複製代碼 代碼如下:System.Text.StringBuilder output = new System.Text.StringBuilder();
HttpCookie aCookie;
string subkeyName;
string subkeyValue;

for (int i = 0; i < Request.Cookies.Count; i++)
{
aCookie = Request.Cookies[i];
output.Append("Name = " + aCookie.Name + "<br />");
if (aCookie.HasKeys)
{
System.Collections.Specialized.NameValueCollection CookieValues =
aCookie.Values;
string[] CookieValueNames = CookieValues.AllKeys;
for (int j = 0; j < CookieValues.Count; j++)
{
subkeyName = Server.HtmlEncode(CookieValueNames[j]);
subkeyValue = Server.HtmlEncode(CookieValues[j]);
output.Append("Subkey name = " + subkeyName + "<br />");
output.Append("Subkey value = " + subkeyValue +
"<br /><br />");
}
}
else
{
output.Append("Value = " + Server.HtmlEncode(aCookie.Value) +
"<br /><br />");
}
}
Label1.Text = output.ToString();

修改和刪除 Cookie

  不能直接修改 Cookie。更改 Cookie 的過程涉及建立一個具有新值的新 Cookie,然後將其發送到瀏覽器來覆蓋用戶端上的舊版本 Cookie。下面的程式碼範例示範如何更改儲存使用者對網站的訪問次數的 Cookie 的值:

複製代碼 代碼如下:int counter;
if (Request.Cookies["counter"] == null)
counter = 0;
else
{
counter = int.Parse(Request.Cookies["counter"].Value);
}
counter++;

Response.Cookies["counter"].Value = counter.ToString();
Response.Cookies["counter"].Expires = DateTime.Now.AddDays(1);

刪除 Cookie刪除 Cookie(即從使用者的硬碟中物理移除 Cookie)是修改 Cookie 的一種形式。由於 Cookie 在使用者的電腦中,因此無法將其直接移除。但是,可以讓瀏覽器來為您刪除 Cookie。該技術是建立一個與要刪除的 Cookie 同名的新 Cookie,並將該 Cookie 的到期日設定為早於當前日期的某個日期。當瀏覽器檢查 Cookie 的到期日時,瀏覽器便會丟棄這個現已到期的 Cookie。下面的程式碼範例示範刪除應用程式中所有可用 Cookie 的一種方法:

複製代碼 代碼如下:HttpCookie aCookie;
string cookieName;
int limit = Request.Cookies.Count;
for (int i=0; i<limit; i++)
{
cookieName = Request.Cookies[i].Name;
aCookie = new HttpCookie(cookieName);
aCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(aCookie);
}

修改或刪除子鍵修改單個子鍵的方法與建立它的方法相同,如下面的樣本所示:

Response.Cookies["userInfo"]["lastVisit"] = DateTime.Now.ToString();
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(1);

若要刪除單個子鍵,可以操作 Cookie 的 Values 集合,該集合用於儲存子鍵。首先通過從 Cookies 對象中擷取 Cookie 來重新建立 Cookie。然後您就可以調用 Values 集合的 Remove 方法,將要刪除的子鍵的名稱傳遞給 Remove 方法。接著,將 Cookie 添加到 Cookies 集合,這樣 Cookie 便會以修改後的格式發送回瀏覽器。下面的程式碼範例示範如何刪除子鍵。在此樣本中,要移除的子鍵的名稱在變數中指定。

複製代碼 代碼如下:string subkeyName;
subkeyName = "userName";
HttpCookie aCookie = Request.Cookies["userInfo"];
aCookie.Values.Remove(subkeyName);
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);

Cookie 和安全性
Cookie 的安全性問題與從用戶端擷取資料的安全性問題類似。在應用程式中,Cookie 是另一種形式的使用者輸入,因此很容易被他們非法擷取和利用。由於 Cookie 儲存在使用者自己的電腦上,因此,使用者至少能看到您儲存在 Cookie 中的資料。使用者還可以在瀏覽器向您發送 Cookie 之前更改該 Cookie。

千萬不要在 Cookie 中儲存敏感資訊,如使用者名稱、密碼、信用卡號等等。不要在 Cookie 中放置任何不應由使用者掌握的內容,也不要放可能被其他竊取 Cookie 的人控制的內容。

同樣,不要輕信從 Cookie 中得到的資訊。不要假定資料與您寫出時相同;處理 Cookie 值時採用的安全措施應該與處理網頁中使用者鍵入的資料時採用的安全措施相同。本主題前面的樣本示範在頁面中顯示值前,先對 Cookie 內容進行 HTML 編碼的方法,這與在顯示從使用者處得到的任何資訊之前的做法相同。

Cookie 以明文形式在瀏覽器和伺服器間發送,任何可以截獲 Web 通訊的人都可以讀取 Cookie。可以設定 Cookie 屬性,使 Cookie 只能在使用安全通訊端層 (SSL) 的串連上傳輸。SSL 並不能防止儲存在使用者電腦上的 Cookie 被讀取或操作,但可防止 Cookie 在傳輸過程中被讀取,因為 Cookie 已被加密。有關更多資訊,請參見 Web 應用程式的基本安全實施策略。

確定瀏覽器是否接受 Cookie
使用者可將其瀏覽器設定為拒絕接受 Cookie。在不能寫入 Cookie 時不會引發任何錯誤。同樣,瀏覽器也不向伺服器發送有關其當前 Cookie 設定的任何資訊。

注意
Cookies 屬性不指示 Cookie 是否啟用。它僅指示當前瀏覽器是否原本支援 Cookie。

確定 Cookie 是否被接受的一種方法是嘗試編寫一個 Cookie,然後再嘗試讀取該 Cookie。如果無法讀取您編寫的 Cookie,則可以假定瀏覽器不接受 Cookie。

下面的程式碼範例示範如何測試瀏覽器是否接受 Cookie。此樣本由兩個頁面組成。第一個頁面寫出 Cookie,然後將瀏覽器重新導向到第二個頁面。第二個頁面嘗試讀取該 Cookie。然後再將瀏覽器重新導向回第一個頁面,並將帶有測試結果的查詢字串變數添加到 URL。

第一個頁面的代碼如下所示:

複製代碼 代碼如下:protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["AcceptsCookies"] == null)
{
Response.Cookies["TestCookie"].Value = "ok";
Response.Cookies["TestCookie"].Expires =
DateTime.Now.AddMinutes(1);
Response.Redirect("TestForCookies.aspx?redirect=" +
Server.UrlEncode(Request.Url.ToString()));
}
else
{
Label1.Text = "Accept cookies = " +
Server.UrlEncode(
Request.QueryString["AcceptsCookies"]);
}
}
}

該頁面首先測試以確定是不是回傳,如果不是,則尋找包含測試結果的查詢字串變數名 AcceptsCookies。如果不存在查詢字串變數,表示測試還未完成,因此代碼會寫出一個名為 TestCookie 的 Cookie。寫出 Cookie 後,該樣本調用 Redirect 來切換到 TestForCookies.aspx 測試頁。附加到測試頁 URL 的資訊是一個名為 redirect 的查詢字串變數,該變數包含當前頁的 URL;這樣就能在執行測試後重新導向回此頁面。

測試頁可完全由程式碼群組成;不需要包含控制項。下面的程式碼範例闡釋了該測試頁。

複製代碼 代碼如下:protected void Page_Load(object sender, EventArgs e)
{
string redirect = Request.QueryString["redirect"];
string acceptsCookies;
if(Request.Cookies["TestCookie"] ==null)
acceptsCookies = "no";
else
{
acceptsCookies = "yes";
// Delete test cookie.
Response.Cookies["TestCookie"].Expires =
DateTime.Now.AddDays(-1);
}
Response.Redirect(redirect + "?AcceptsCookies=" + acceptsCookies,
true);
}

讀取重新導向查詢字串變數後,代碼嘗試讀取 Cookie。出於管理目的,如果該 Cookie 存在,則立即刪除。測試完成後,代碼通過 redirect 查詢字串變數傳遞給它的 URL 構造一個新的 URL。新 URL 也包括一個包含測試結果的查詢字串變數。最後一步是使用新 URL 將瀏覽器重新導向到最初頁面。

該樣本的一個改進是可將 Cookie 測試結果儲存到永久儲存區(如資料庫)中,這樣就不必在使用者每次查看最初頁面時都重複進行測試。(預設情況下,在工作階段狀態中儲存測試結果需要 Cookie。)

Cookie 和工作階段狀態
當使用者導航到您的網站時,伺服器為該使用者建立唯一的會話,會話將一直延續到使用者訪問結束。ASP.NET 會為每個會話維護工作階段狀態資訊,應用程式可在工作階段狀態資訊中儲存使用者特定資訊。有關更多資訊,請參見工作階段狀態概述主題。

ASP.NET 必須跟蹤每個使用者的會話 ID,以便可以將使用者映射到伺服器上的工作階段狀態資訊。預設情況下,ASP.NET 使用非永續性 Cookie 來儲存工作階段狀態。但是,如果使用者已在瀏覽器上禁用 Cookie,工作階段狀態資訊便無法儲存在 Cookie 中。

ASP.NET 提供了無 Cookie 會話作為替代。可以將應用程式配置為不將會話 ID 儲存在 Cookie 中,而儲存在網站中頁面的 URL 中。如果應用程式依賴於工作階段狀態,可以考慮將其配置為使用無 Cookie 會話。但是在較少的情況下,如果使用者與他人共用 URL(可能是使用者將 URL 發送給同事,而該使用者的會話仍然處於活動狀態),則最終這兩個使用者可能共用同一個會話,結果將難以預料。有關將應用程式配置為使用無 Cookie 會話的更多資訊,請參見 ASP.NET 狀態管理概述主題。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.