维护Web应用程序状态(1)——Cookie

  rel="File-List" href="file:///C:%5CDOCUME%7E1%5C%E8%B5%96%E5%BC%BA%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml">

       那些刚刚进入Web编程的开发人员,总是难以理解维护应用程序状态的问题。万维网最基础的协议是HTTP协议是一个无状态协议,也就是说,从Web服务器端的角度看,每一个访问请求都是一个新的用户。HTTP协议不提供任何方法来决定两个访问请求是否是同一个用户发出的。

       然而,维护状态对任何Web应用程序来说都是非常重要的。

       ASP.NET 2.0 Framework中,包含以下三种在多个页面请求间关联数据和特定用户的方法:

*         浏览器cookie:浏览器cookie用于关联一些文本到网站的每一个用户。

*         会话状态(session state:会话状态用于关联任意类型的对象到任何用户。

*         Profile对象profile对象提供一个创建强类型和持久化方式的会话状态的方法。

 

使用浏览器cookie

       Cookie是如何工作的呢?当Web服务器端创建一个cookie时,一个附加的HTTP首部在浏览器显示页面时被发送到浏览器。HTTP首部类似如下格式:

       Set-Cookie:message=Hello

       Set-Cookie首部使得浏览器创建一个名为messagecookie,包含值Hello

       在浏览器创建cookie后,它从相同的应用程序请求页面时,都将像下面这样发送这个HTTP首部:

       Cookie:message=Hello

       Cookie头包含所有的Web服务器端设置的cookie。每次浏览器向Web服务器端请求页面时,cookie都会发送回服务器端。

       注意,一个cookie就是一段文本。Cookie只能用于存储字符串值。

       实际上,我们可以存储两种类型的cookie:会话cookie和持久化cookie。一个会话cookie只存在于内存中。当用户关闭浏览器时,会话cookie就永远消失了。

       而持久化cookie可以存在几个月设置几年。当创建一个持久化cookie时,cookie被浏览器长久存在用户的电脑上。以IE为例,cookie以一组文本文件的形式保存在下面的文件夹:

       /Documents and Settings/[user]/Cookies

       另一方面,对于Mozilla Firefox浏览器则将cookie保存在下面文件夹:

       /Documents and Settings/[user]/Application Data/Mozilla/Firefox/Profiles/[random folder name]/Cookies.txt

       应注意IEFirefox浏览器都以明文形式存储cookie。所以不应该将诸如社会保险号,或信用卡号码之类的敏感信息存于cookie中。

 

1  cookie的安全性限制

       为了避免电脑遭到袭击,浏览器对cookie有一些强制的安全显示。

       首先,所有的cookie是域名独立的。163网易设置的cookieyahoo网站访问不到。浏览器创建一个cookie时,会记录关联到cookie的域名,不会将其发送到另一个域名。

       其次,浏览器存储cookie的重要限制是其大小的限制。一个域名存储的cookie总大小不能超过4096byte。这个大小限制,包含所有的cookie名称和值在内。

       最后,大多数浏览器都限制可以被设置的cookie数量,一个域名不超过20cookie(不包括IE浏览器)。超过这个数目,旧的cookie会被自动删除。

 

2  创建cookie

       可以通过Response.Cookies集合添加cookie来创建新的cookieResponse.Cookies集合包含所有的Web服务器端发送到Web浏览器的cookie

       代码清单1所示的页面创建一个新的名叫Messagecookie。该页面包括一个输入Message这个cookie值的表单。

       代码清单1SetCookie.aspx

       前台:SetCookie.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CookieDemo._Default" %>

 

<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <asp:Label ID="lblCookieValue" Text="Cookie Value:" AssociatedControlID="txtCookieValue" runat="server" />

        <asp:TextBox ID="txtCookieValue" runat="server" />

        <asp:Button ID="btnAdd" Text="Add Value" runat="server" OnClick="btnAdd_Click" />

    </div>

    </form>

</body>

</html>

       后台:SetCookie.aspx.cs

protected void btnAdd_Click(object sender, EventArgs e)

{

    Response.Cookies["message"].Value = txtCookieValue.Text;

}

       注意,cookie的名称是大小写敏感的。设置一个名叫messagecookie和设置一个名叫Messagecookie是不同的。

       代码清单1所示的页面创建的是一个会话cookieseesion cookie)。当关闭Web浏览器时,该cookie就消失了。如果希望创建持久化cookiepersistent cookie),则需要为cookie指定一个过期时间。

       代码清单2所示的页面创建了一个持久化的cookie

       代码清单2SetPersistentCookie.aspx

       前台:SetPersistentCookie.aspx代码

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SetPersistentCookie.aspx.cs" Inherits="CookieDemo.SetPersistentCookie" %>

 

<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Set Persistent Cookie</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        You have visited this page

        <asp:Label ID="lblCounter" runat="server" />

        times!

    </div>

    </form>

</body>

</html>

       后台:SetPersistentCookie.aspx.cs代码

        protected void Page_Load(object sender, EventArgs e)

        {

            // Get current value of cookie

            int counter = 0;

            if (Request.Cookies["counter"] != null)

            {

                counter = Int32.Parse(Request.Cookies["counter"].Value);

            }

            // Increment counter

            counter++;

 

            // Add persistent cookie to browser

            Response.Cookies["counter"].Value = counter.ToString();

            Response.Cookies["counter"].Expires = DateTime.Now.AddYears(2);

 

            // Display value of counter cookie

            lblCounter.Text = counter.ToString();

        }

       代码清单2所示的页面记录页面被请求的次数。一个名为counter的持久化cookie被用来记录页面被请求的次数。注意,counter的过期时间被设为2年以后。当为某个cookie设置了过期时间后,cookie就被保存为持久化cookie了。

 

3  读取cookie

       可以使用Response.Cookies集合创建和修改cookie,也可以使用Request.Cookies集合读取cookie的值。

       代码清单3获取Request.Cookies集合中的所有cookie

            ArrayList colCookie = new ArrayList();

            for (int i = 0; i < Request.Cookies.Count; i++)

            {

                colCookie.Add(Request.Cookies[i]);

            }

       使用Request.Cookies集合时,非常重要的一点是,理解For…Each循环返回的值和For…Next循环返回的值的不同。如果用For…Each循环迭代Request.Cookies集合,返回的是cookies的名称。如果用For…Next循环迭代该集合,返回的是HttpCookie类的示例。

 

4  设置cookie属性

       HttpCookie类代表cookie。当创建或读取一个cookie时,可以使用该类的下面这些属性。

n         Domain——用于设置关联到cookie的域名,默认值是当前域名。

n         Expires——用于通过给定一个过期时间创建一个持久化cookie

n         HasKeys——用于指定该cookie是否是一个多值cookie

n         HttpOnly——用于避免cookieJavaScript访问。

n         Name——用户指定cookie的名称。

n         Path——用于指定关联到cookie的路径。默认值为/

n         Secure——用于指定cookie需要通过安全Socket层(SSL)连接传递。

n         Value——允许读/cookie的值。

n         Values——当使用多值cookie时,用户读/写特定的值。

这些属性中的一部分需要更多的解释。例如,你可能发现Domain属性有些奇怪,因为你修改不了关联到cookiedomain

       Domain属性对于组织子域名时会非常有用。如果需要设置cookie可以被Sales.MyCompany.comManagers.MyCompany.comSupport.MyCompany.com访问,则需要设置Domain属性值为.MyCompany.com(注意开头的部分),而不能使用该属性关联cookie到一个完全不同的域名。

       HttpOnly属性用于设置一个cookie是否可以通过JavaScript访问。该属性只能对IE6SP1)及以上版本有效。引入该属性是为了防止跨站点脚本攻击。

       Path属性用于限定cookie到一个特定的路径。例如,如果在相同的域名部署多个应用程序,而不希望应用程序共享相同的cookie,则需要设置Path属性避免一个应用程序读取另一个应用程序的cookie

       Path属性听起来很有用。不幸的是,你不应该使用它。IE对于路径是大小写敏感的。如果用户在地址输入一个不同大小写的路径,则cookie不会被发送。换句话说,下面两个路径不匹配:

       http://localhost/original/GetAllCookies.aspx

       http://localhost/ORIGINAL/GetAllCookies.aspx

 

5  删除cookie

       删除一个cookie的方法并不直观。要删除一个存在的cookie,必须设置其过期时间为一个过去的时间。

       例如,代码清单4

     // 删除指定cookie

     Response.Cookies["cookie"].Expires = DateTime.Now.AddDays(-1);

       代码清单5所示的是删除当前域名(和路径)下的所有cookie

     // 删除域名下的所有cookie

     string[] cookies = Request.Cookies.AllKeys;

     foreach (string cookie in cookies)

     {

         Response.Cookies[cookie].Expires = DateTime.Now.AddDays(-1);

     }

       代码清单5所示的从Request.Cookies集合中循环遍历并删除所有的cookie

 

6  使用多值cookie

       根据cookie规范,对单个域名,浏览器不能存储超过20cookie。可以通过创建多值cookie来超越该限制。多值cookie是一个包含子键的单一cookie。可以根据需要创建任意数量的子键。

       例如,代码清单6所示创建了一个名为preferences的多值cookiePreferences cookie用于存储first name(名)、last name(姓)和favorite color(喜爱的色彩)

    // 创建多值cookie

     Response.Cookies["perferences"]["firstname"] = "God";

     Response.Cookies["perferences"]["lastname"] = "Heaven";

     Response.Cookies["perferences"]["favoriteColor"] = "White";

     Response.Cookies["perferences"].Expires = DateTime.MaxValue;

       当提交代码清单6所示页面时,下面的HTTP首部被发送到浏览器:

       Set-Cookie:preferences=firstname=God&lastname=Heaven&favoriteColor=White;

       expires=Fri,31-Dec-9999 23:59:59 GMT; path=/

       代码清单7所示从preferences cookie读取值

     // 读取多值cookie

     if (Request.Cookies["perferences"] != null)

     {

         string strFirstName = Request.Cookies["perferences"]["firstname"];

         string strLastName = Request.Cookies["perferences"]["lastname"];

         string strFavoriteColor = Request.Cookies["perferences"]["favoriteColor"];

     }

       可以使用HttpCookie.HasKey属性判断一个cookie是一个普通cookie还是一个多值cookie


下篇将介绍会话状态(Seesion)的状态维护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值