【转】【C#.NET】ASP.NET状态管理之一:Cookie
【C#.NET】ASP.NET狀態管理之一:Cookie
狀態管理是你對同一頁或不同頁的多個請求維護狀態和頁信息的過程。與所有基于 HTTP 的技術一樣,Web 窗體頁是無狀態的,這意味著它們不自動指示序列中的請求是否全部來自相同的客戶端,或者單個瀏覽器實例是否一直在查看頁或站點。此外,到服務器的每一往返過程都將銷毀并重新創建頁;因此,如果超出了單個頁的生命周期,頁信息將不存在。比如,我們在代碼中聲明一個DataSet從數據庫獲取記錄,頁面回發(也就是重新請求)后這個DataSet是空的,這就是為什么在ASP.NET應用程序中,甚至在一個頁面中需要多次連接數據庫獲取記錄。正是由于這個原因,狀態管理對于Web編程來說非常重要,從第一代動態Web編程語言開始就支持多種狀態管理以彌補HTTP無狀態的不足。
現在的Web應用程序,通常都是數據驅動的,但是在狀態處理中,我們應該盡量減少對數據庫的依賴,原因如下。
·????? 數據庫是存放在磁盤上的。如果把數據存放在數據庫中的話,性能會比較差。
·????? 很多數據是和用戶相關的。如果把數據存放在數據庫中的話,我們沒有一個唯一的標志來區分哪條記錄對應哪個客戶端(瀏覽器)。
·????? 很多數據是臨時的,用戶關閉了瀏覽器這些數據就不再需要了。如果把數據存放在數據庫中的話,我們不知道是哪個用戶關閉了瀏覽器,也就不能及時把數據刪除。
通常來講,狀態管理的作用主要概括為以下幾點。
·????? 指示用戶信息,關聯瀏覽器實例。
·????? 使得頁與頁之間,請求與請求之間能夠共享信息。
·????? 更為快速的數據存儲與讀取。
?
一、Cookie概述
?
Cookie 為 Web 應用程序保存用戶相關信息提供了一種有用的方法。例如,當用戶訪問站點時,可以利用 Cookie 保存用戶首選項或其他信息,這樣,當用戶下次再訪問站點時,應用程序就可以檢索以前保存的信息。
從技術上講,Cookie是小段保存在客戶端的數據(如果你安裝的是XP,可以看一下<安裝Windows的盤>:"Documents and Settings"<用戶名>"Cookies文件夾)。用戶訪問網站的時候,網站會給用戶一個包含過期時間的Cookie,瀏覽器收到Cookie后就存放在客戶端的文件夾下。以后用戶每次訪問網站頁面的時候,瀏覽器會根據網站的URL在本地Cookie文件夾內查找是否存在當前網站關聯的Cookie,如果有的話就連同頁面請求一起發送到服務器。
關于Cookie的知識還需要了解以下幾點。
·????? Cookie只是一段字符串,并不能執行。
·????? 大多數瀏覽器規定Cookie大小不超過4K,每個站點能保存的Cookie不超過20個,所有站點保存的Cookie總和不超過300個。
·????? 除了Cookie外,幾乎沒有其他的方法在客戶端的機器上寫入數據(就連Cookie的寫入操作也是瀏覽器進行的)。當然,連Cookie都可以通過瀏覽器安全配置來禁止。如果你使用IE瀏覽器,可以看一下“工具”→“Internet”選項→“隱私”一頁。現在的大多數網站都利用Cookie來保存一些數據(比如你的ID),以便你下一次訪問網站時能直接“繼續”以前的配置,所以我還是建議你不要輕易關閉Cookie。
在使用Cookie時,必須意識到其固有的安全弱點。Cookie畢竟是存放于客戶端的。因此,不要在Cookie中保存保密信息,如用戶名、密碼、信用卡號等。在Cookie中不要保存不應該由用戶掌握的內容,也不要保存可能被其他竊取Cookie的人控制的內容。
二、??Cookie的使用
下面,我們就來討論如何保存、讀取、刪除和修改Cookie。首先在頁面上添加4個按鈕用來完成這4個操作。
<asp:Button ID="btn_SaveCookie" runat="server" OnClick="btn_SaveCookie_Click"
Text="保存Cookie" />
<asp:Button ID="btn_ReadCookie" runat="server" Text="讀取Cookie"
OnClick="btn_ReadCookie_Click" />
<asp:Button ID="btn_ModifyCookie" runat="server" OnClick="btn_ModifyCookie_Click"
Text="修改Cookie" />
<asp:Button ID="btn_DelCookie" runat="server" Text="刪除Cookie"
OnClick="btn_DelCookie_Click" />
保存Cookie的方法如下。
protected void btn_SaveCookie_Click(object sender, EventArgs e)
{
??? HttpCookie SingleValueCookie = new HttpCookie("test1", "單值Cookie");
??? SingleValueCookie.Expires = DateTime.Now.AddDays(1);
??? Response.Cookies.Add(SingleValueCookie);
??? HttpCookie MultiValueCookie = new HttpCookie("test2");
??? MultiValueCookie.Values.Add("key1", "value1");
??? MultiValueCookie.Values.Add("key2", "value2");
??? MultiValueCookie.Expires = DateTime.Now.AddDays(1);
??? Response.Cookies.Add(MultiValueCookie);
}
我們可以看到,一個Cookie中允許保存單個值也可以保存多個值。HttpCookie類型表示一個Cookie,Expires屬性用于修改Cookie的過期時間。對于單值Cookie,既可以直接在構造方法中指定值也可以使用Value屬性指定值。對于多值Cookie,既可以使用Values屬性的Add方法添加子鍵和值,也可以直接使用Values屬性的索引設置子鍵和值。上面這段代碼等價于下面這段代碼。
protected void btn_SaveCookie_Click(object sender, EventArgs e)
{
??? HttpCookie SingleValueCookie = new HttpCookie("test1");
??? SingleValueCookie.Value = "單值Cookie";
??? SingleValueCookie.Expires = DateTime.Now.AddDays(1);
??? Response.Cookies.Add(SingleValueCookie);
??? HttpCookie MultiValueCookie = new HttpCookie("test2");
??? MultiValueCookie.Values["key1"] = "value1";
??? MultiValueCookie.Values["key2"] = "value2";
??? MultiValueCookie.Expires = DateTime.Now.AddDays(1);
??? Response.Cookies.Add(MultiValueCookie);
}
在添加完值以后,務必記得使用Response對象把Cookie重新返回給瀏覽器。我們的服務器不能直接在客戶端機器上寫Cookie,而是由瀏覽器完成這一工作,當然用戶也可以設置是否允許瀏覽器讀寫Cookie。
下面是讀取Cookie的操作。
protected void btn_ReadCookie_Click(object sender, EventArgs e)
{
??? HttpCookie SingleValueCookie = Request.Cookies["test1"];
??? if (SingleValueCookie != null)
??? {
??????? Response.Write(string.Format("Key:{0} Value:{1} Expires:{2}<br/>", "test1",
??????? SingleValueCookie.Value, SingleValueCookie.Expires));
??? }
??? HttpCookie MultiValueCookie = Request.Cookies["test2"];
??? if (MultiValueCookie!= null)
??? {
??????? Response.Write(string.Format("Key:{0} Value:{1}<br/>", "test2", MultiValueCookie.
????????? Value));
??????? foreach (string subkey in MultiValueCookie.Values.AllKeys)
??????? {
??????????? Response.Write(string.Format("SubKey:{0} Value:{1} Expires:{2}<br/>",
??????????? subkey, MultiValueCookie.Values[subkey], MultiValueCookie.Expires));
??????? }
??? }
}
對于多值Cookie,我們通過遍歷AllKeys屬性返回的字符串數組獲取所有子鍵Key,從而獲得子鍵的值。要注意的是,在訪問Cookie以前,需要檢測一下Cookie是否存在。打開頁面,先單擊“保存Cookie”按鈕,然后單擊“讀取Cookie”按鈕,得到以下輸出:
Key:test1 Value:單值Cookie Expires:0001-1-1 0:00:00
Key:test2 Value:key1=value1&key2=value2
SubKey:key1 Value:value1 Expires:0001-1-1 0:00:00
SubKey:key2 Value:value2 Expires:0001-1-1 0:00:00
這里要說明以下幾點。
·????? 我們發現,所有Cookie的過期時間都不能正常顯示。這是因為瀏覽器返回給服務器的Cookie是不包含過期時間的,而服務器返回給瀏覽器的Cookie是包含過期時間的。過期時間只對客戶端瀏覽器有意義,對服務器來說沒有什么意義。
·????? 直接讀取多值Cookie的Value,它會把所有子鍵和子鍵值都使用key=value方法顯示,多個子鍵使用“&”連接(類似URL的方式)。
下面是刪除Cookie的操作。
protected void btn_DelCookie_Click(object sender, EventArgs e)
{
??? HttpCookie SingleValueCookie = Request.Cookies["test1"];
??? SingleValueCookie.Expires = DateTime.MinValue;
??? Response.Cookies.Add(SingleValueCookie);
}
如果你想刪除所有Cookie,可以遍歷刪除。
protected void btn_DelCookie_Click(object sender, EventArgs e)
{
??? foreach (string key in Request.Cookies.AllKeys)
??? {
??????? HttpCookie cookie = Request.Cookies[key];
??????? cookie.Expires = DateTime.MinValue;
??????? Response.Cookies.Add(cookie);
??? }
}
我們始終要記住,服務器不能直接刪除Cookie,刪除Cookie的操作是瀏覽器進行的。說是刪除,其實是把它的過期時間設置為過去的時間,讓Cookie過期。因此,對于刪除操作來說有三個步驟。
1.從Request對象中獲取Cookie。
2.把Cookie的過期時間設置為過去的時間。
3.把Cookie重新寫回Response中。
4.修改Cookie的操作也非常簡單。
protected void btn_ModifyCookie_Click(object sender, EventArgs e)
{
??? HttpCookie SingleValueCookie = Request.Cookies["test1"];
??? SingleValueCookie.Value = "修改后的單值Cookie";
??? Response.Cookies.Add(SingleValueCookie);
}
三、?Cookie總結
Cookie雖然是一個簡單實用的對象,但是我們也要注意Cookie的工作原理、大小限制以及安全性等,大致可以歸納為以下幾點。
·????? 存儲的物理位置。客戶端的Cookies文件夾內。
·????? 存儲的類型限制。字符串。
·????? 狀態使用的范圍。當前請求上下文的上下文都能訪問到Cookie,Cookie對每個用戶來說都是獨立的。
·????? 存儲的大小限制。每個Cookie不超過4K數據。每個網站不超過20個Cookie。所有網站的Cookie總和不超過300個。
·????? 生命周期。每個Cookie都有自己的過期時間,超過了過期時間后失效。
·????? 安全與性能。存儲在客戶端,安全性差。對于敏感數據建議加密后存儲。
·????? 優點缺點與注意事項。可以很方便地關聯網站和用戶,長久保存用戶設置。
轉載于:https://www.cnblogs.com/xust/articles/3399387.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【转】【C#.NET】ASP.NET状态管理之一:Cookie的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spark快速大数据分析——Spark的
- 下一篇: C++ 0x 使用可变参数模板类 实现