6.Cookie7.Session原理 7.1案例:用Session實現驗證碼。
6.Cookie
表單是和頁面相關的,只有瀏覽器端提交了這些資料服務器端才能得到。而有時候希望在服務端任意的地方存取一些和訪問者相關的資訊,這時候就不方便將這些資訊儲存到表單中了,因為如果那樣的話必須隨時注意在所有頁面表單中都儲存這些資訊。Cookie是和網站相關的,並且每次向伺服器請求的時候除了發送表單參數外,還會將和網站相關的所有Cookie都提交給伺服器,是強制性的。Cookie也是儲存在瀏覽器端的,而且瀏覽器會在每次請求的時候都會把和這個網站的相關的Cookie提交到伺服器,並且將服務端返回的Cookie更新回資料庫,因此可以將資訊儲存在Cookie中,然後在伺服器端讀取、修改。伺服器返回資料除了普通的html資料以外,還會返回修改的Cookie,瀏覽器把拿到的Cookie值更新本地瀏覽器的Cookie就可以。
案例:
cookie1.aspx
cookie1.aspx.cs
protected void Button1_Click(object sender, EventArgs e) { Response.SetCookie(new HttpCookie("color",TextBox1.Text));//在用戶端也能通過$.cookie取。服務端設定cookie }
下面是第二個頁面
cookie讀2.aspx
cookie讀2.aspx.cs
protected void Button1_Click(object sender, EventArgs e) { Label1.Text = Request.Cookies["color"].Value; }
7.Session原理
Cookie不能儲存過多資訊。如果想儲存大量的資料,可以儲存一個Guid到Cookie中,然後在伺服器中建立一個以Guid為Key,複雜資料為Value全域Dictionary。static欄位對於不同使用者也只有一份,因此用static實現多使用者共用資料。代碼見備忘※。
變數1.aspx
變數1.aspx.cs
public partial class 變數1 : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { //給cookie為MySessionId賦值,guid if (Request.Cookies["MySessionId"] == null) { string sessionId = Guid.NewGuid().ToString(); Response.Cookies["MySessionId"].Value = sessionId; } } //設定session protected void Button2_Click(object sender, EventArgs e) { string sessionId = Request.Cookies["MySessionId"].Value; IDictionary<string, object> session = SessionMgr.GetSession(sessionId); session["服務端的資料"] = 3333; } //讀取session protected void Button1_Click(object sender, EventArgs e) { string sessionId = Request.Cookies["MySessionId"].Value; IDictionary<string, object> session = SessionMgr.GetSession(sessionId); Label1.Text = session["服務端的資料"].ToString(); }}
SessionMgr.cs
public class SessionMgr{ public SessionMgr() { // // TODO: 在此處添加建構函式邏輯 // } private static IDictionary<string, IDictionary<string, object>> data = new Dictionary<string, IDictionary<string, object>>(); public static IDictionary<string,object> GetSession(string sessionId) { if (data.ContainsKey(sessionId)) { return data[sessionId]; } else { IDictionary<string ,object> session = new Dictionary<string, object>(); data[sessionId] = session; return session; } }}
ASP.Net已經內建了Session機制,把上面的例子用ASP.NetSession重寫。不要放太多的對象到Session,Session會有逾時銷毀的機制,發帖(伺服器不可能知道瀏覽器是否在開著,什麼時候關閉),發帖計時,線上時間統計,靠請求來判斷是否活著。Cookie是存在用戶端,Session是存在伺服器端,目的是一樣的:儲存和當前用戶端相關的資料(當前網站的任何一個頁面都能取到Session、Cookie)。不能放太大的資料,放的資料是object。
7.1案例:用Session實現驗證碼。
HttpHandler要能夠操作Session,要實現IRequiresSessionState介面。為什麼每次點擊值都變化?很正常,因此每次頁面點擊頁面都會重新整理,就向ashx重新請求圖片,ashx的ProcessRequest都會執行。正常網站登入成功就進入首頁面,沒機會讓你看到變化,但是一旦輸入錯誤也是變化。
1.建立YZM.ashx
<%@ WebHandler Language="C#" Class="YZM" %>using System;using System.Drawing;using System.Web;using System.Web.SessionState;//HttpHandler使用Session要調用IRequiresSessionState介面public class YZM : IHttpHandler, IRequiresSessionState{ public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/JPEG"; using (Bitmap bitmap = new Bitmap(50, 30)) { using (Graphics g = Graphics.FromImage(bitmap)) { //隨機的驗證碼 Random ran = new Random(); int code = ran.Next(1,9999); string strCode = code.ToString(); //寫到Session裡 HttpContext.Current.Session["Code"] = strCode; g.DrawString(strCode,new Font("微軟雅黑",12),Brushes.Wheat,new PointF(0,0)); bitmap.Save(context.Response.OutputStream,System.Drawing.Imaging.ImageFormat.Jpeg); } } } public bool IsReusable { get { return false; } }}
2.建立頁面
<body> <form id="form1" runat="server"> <div>
<img src="YZM.ashx"/>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /> </div> </form></body>
3.在驗證碼驗證.aspx.cs代碼裡寫
protected void Button1_Click(object sender, EventArgs e) { string yzm = Convert.ToString((Session["Code"])); if (yzm == TextBox1.Text) { Response.Write("正確"); } else { Response.Write("錯誤"); } }
點擊圖片產生新的驗證碼。 <img src="YZM.ashx" onclick="this.src='YZM.ashx?aaa='+new Date()" />每次點擊都
產生一個新的地址,讓瀏覽器去請求。在AJAX中還會用。