ASP.NET中Cookie编程的基础知识(4)

控制 Cookie 有效范围

默认情况下,一个站点的全部 Cookie 都一起保存在客户机上,而且所有这些 Cookie 都会随着对该站点发送的请求一起发送到服务器,也就是说,站点的每个页面都能得到该站点的所有 Cookie。但有时候,您可能希望 Cookie 更具有针对性,这时,您可以通过两种方法设置 Cookie 的有效范围:

把 Cookie 的有效范围限制在服务器上的一个文件夹中,实际上这样就将 Cookie 限制到站点上的某个应用程序。

把有效范围设置为某个域,从而允许您指定域中的哪些子域可以访问 Cookie。

将 Cookie 限制到某个文件夹或应用程序

要将 Cookie 限制到服务器上的某个文件夹,请按如下方法设置 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)

当然,您也可以通过直接设置 Response.Cookies 来编写 Cookie,如前文所述。

路径可以是站点根目录下的物理路径,也可以是虚拟根目录。这样一来,Cookie 就只能用于 Application1 文件夹或虚拟根目录中的页面。例如,如果您的站点名为 www.contoso.com ,则前面示例中生成的 Cookie 就只能用于路径为 http://www.contoso.com/Application1/ 的页面以及该文件夹下的所有页面,而不适用于其他应用程序中的页面,如 http://www.contoso.com/Application2/http://www.contoso.com/ 下的页面。

提示:通过对 Internet Explorer 和 Mozilla 浏览器进行测试发现,此处使用的路径是区分大小写的。一般而言,Windows 服务器上的 URL 不区分大小写,但这种情况例外。您无法控制用户如何在浏览器中输入 URL,但是,如果您的应用程序依赖于与特定路径相关的 Cookie,则请确保您所创建的所有超链接中的 URL 与 Path 属性值的大小写相匹配。

将 Cookie 的有效范围限制到域

默认情况下,Cookie 与特定的域相关联。例如,如果您的站点是 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 应用程序中,您可以使用 Request 对象来读取 Cookie。Request 对象的结构与 Response 对象的结构基本相同,所以从 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 的值之前,应该确保该 Cookie 确实存在。否则,您将得到一个 System.NullReferenceException(英文)异常。还需要注意的是,在页面中显示 Cookie 的内容之前,我调用了 HttpServerUtility.HtmlEncode(英文)方法对 Cookie 的内容进行编码。之所以这样做,是因为我要显示 Cookie 的内容(一般您不会这样做)而且要确保没有任何恶意用户在 Cookie 中添加了可执行脚本。有关 Cookie 安全性的详细信息,请参阅 Cookie 和安全性。

注意:由于不同的浏览器保存 Cookie 的方式也不同,所以同一台计算机上的不同浏览器不一定能够相互读取各自的 Cookie。例如,如果使用 Internet Explorer 测试一个页面,然后再使用其他浏览器进行测试,那么后者就不会找到 Internet Explorer 保存的 Cookie。当然,大多数人一般都是使用同一种浏览器进行 Web 交互的,因此在大多数情况下不会出现问题。但有时还是会遇到问题,比如您要测试应用程序对浏览器的兼容性。

读取 Cookie 中子键值的方法与设置该值的方法类似。以下是获取子键值的一种方法:

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

在上面的示例中,我获取的是子键“lastVist”的值,在此前的讨论中我把该值设置为 DateTime 值的字符串表示形式。请记住,Cookie 是用字符串的形式保存值的,所以要将 lastVisit 值用作日期,就必须对其进行转换:

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

就像设置 Cookie 一样,使用哪种方法读取 Cookie 也由您自己决定。

什么是有效期?

您可以读取 Cookie 的名称和值,除此以外,需要了解的有关 Cookie 的信息并不是很多。虽然您可以获取 Domain 和 Path 属性,但是这些属性的用途很有限。例如,您可以读取 Domain 属性,但如果您的页面与 Cookie 不在相同的域,您根本就不会在页面的位置接收到该 Cookie。

您无法读取的是 Cookie 的过期日期和时间。事实上,当浏览器向服务器发送 Cookie 信息时,浏览器并未将过期信息包括在内。您可以读取 Expires 属性,但总是返回为零的日期/时间值。

在前面的编写 Cookie 一节中,我已经讲过,是浏览器负责管理 Cookie 的,Expires 属性就很好地印证了这一点。Expires 属性的主要作用是帮助浏览器执行有关 Cookie 保存的日常管理。从服务器的角度来看,Cookie 要么存在要么不存在,所以对服务器而言,有效期并不是有用的信息。所以,浏览器在发送 Cookie 时并不提供此信息。如果您需要 Cookie 的过期日期,就必须重新设置,关于这一点我将在修改和删除 Cookie 中介绍。

更确切地说,您可以在向浏览器发送 Cookie 之前读取已在 Response 对象中设置的 Expires 属性,但您无法从返回的 Request 对象中获取有效期信息。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus