什么是 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 来存储少量数据,或者存储用户 ID 之类的标识符。用户 ID 随后便可用于标识用户,以及从数据库或其他数据源中读取用户信息。(有关存储用户信息安全建议的信息,请参见下面的“Cookie 和安全性”一节。)
浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储 20 个 Cookie;如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。有些浏览器还会对它们将接受的来自所有站点的 Cookie 总数作出绝对限制,通常为 300 个。
您可能遇到的 Cookie 限制是用户可以将其浏览器设置为拒绝接受 Cookie。如果定义一个 P3P 隐私策略,并将其放置在网站的根目录中,则更多的浏览器将接受您站点的 Cookie。但是,您可能会不得不完全放弃 Cookie,而通过其他机制来存储用户特定的信息。存储用户信息的常用方法是会话状态,但会话状态依赖于 Cookie,这一点在后面的“Cookie 和会话状态”一节中说明。
虽然 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 添加到 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 文件夹或虚拟根目录中的页面。例如,如果您的站点名称为 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 与特定域关联。例如,如果您的站点是 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
值作为日期使用,必须将其转换为适当的类型,如此示例所示:
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();
注意 |
---|
在运行此代码时,可能会看到一个名为 |
上面的示例有一个限制:如果 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 的一种方法:
修改或删除子键
修改单个子键的方法与创建它的方法相同,如下面的示例所示:
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 便会以修改后的格式发送回浏览器。下面的代码示例演示如何删除子键。在此示例中,要移除的子键的名称在变量中指定。
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 状态管理概述主题。
什么是 Cookie的更多相关文章
- 超大 Cookie 拒绝服务攻击
有没有想过,如果网站的 Cookie 特别多特别大,会发生什么情况? 不多说,马上来试验一下: for (i = 0; i < 20; i++) document.cookie = i + '= ...
- IE10、IE11 User-Agent 导致的 ASP.Net 网站无法写入Cookie 问题
你是否遇到过当使用一个涉及到Cookie操作的网站或者管理系统时,IE 6.7.8.9下都跑的好好的,唯独到了IE10.11这些高版本浏览器就不行了?好吧,这个问题码农连续2天内遇到了2次.那么,我们 ...
- 解决cookie跨域访问
一.前言 随着项目模块越来越多,很多模块现在都是独立部署.模块之间的交流有时可能会通过cookie来完成.比如说门户和应用,分别部署在不同的机器或者web容器中,假如用户登陆之后会在浏览器客户端写入c ...
- jquery插件的用法之cookie 插件
一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...
- 一个诡异的COOKIE问题
今天下午,发现本地的测试环境突然跑不动了,thinkphp直接跑到异常页面,按照正常的排错思路,直接看thinkphp的log 有一条 [ error ] [2]setcookie() expects ...
- [转载]Cookie/Session的机制与安全
Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道.本文来详细讨论Cookie和Session的实现机制,以及其中涉及的安全问题. 因 ...
- jquery.cookie的使用
今天想到了要为自己的影像日记增加赞的功能,并且需要用到cookie. 记得原生的js操作cookie也不是很麻烦的,但似乎jquery更简单,不过相比原生js,需要额外引入2个文件,似乎又不是很好,但 ...
- 跨域问题,前端主动向后台发送cookie
跨域是什么? 从一个域名的网页访问另一个域名的资源,就会出现跨域.只要协议.端口.域名有一个不同就会出现跨域 例如: 1.协议不同 http://www.baidu.com:80 和 https:/ ...
- 【流量劫持】沉默中的狂怒 —— Cookie 大喷发
精简版:http://www.cnblogs.com/index-html/p/mitm-cookie-crack.html 前言 上一篇文章 讲解了如何借助前端技术,打造一个比 SSLStrip 更 ...
- 好好了解一下Cookie
Cookie的诞生 由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的.Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用.比如判断用户是否是第一次访问网站.目前最新 ...
随机推荐
- Centos6.5(Linux)安装Nginx
1.安装nginx依赖的库pcre 下载地址:http://sourceforge.net/projects/pcre/ 2.解压pcre zip解压方式:unzip ...
- ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(三) 激动人心的时刻到啦,实现1v1聊天
看起来挺简单,细节还是很多的,好,接上一篇,我们已经成功连接singalR服务器了,那么剩下的内容呢,就是一步一步实现聊天功能. 我们先看看缺什么东西 点击好友弹框之后,要给服务器发消息,进入组Gro ...
- Spring 声明式事务管理方式
声明式事务管理,基于AOP对目标代理,添加环绕通知,比编码方案优势,不具有侵入式,不需要修改原来的代码. 1.基于XML配置的声明式事务管理方案(案例) 接口Service public i ...
- c#类的练习
类部分练习题 - dijiaxing1234的博客 - CSDN博客 https://blog.csdn.net/dijiaxing1234/article/details/81230811 真好啊
- sqlite迁移mysql(导入导出数据)
第一步,将数据导出 进入sqlite3->.open [打开文件路径]->.cd [要保存的路径]->.output [导出文件名字.sql]->.dump 等待导出成功后,就 ...
- 【洛谷P2470】[SCOI2007]压缩
压缩 #include<iostream> #include<cstring> #include<cstdio> using namespace std; #def ...
- Android学习笔记_46_Android的intent之间Object、List、List<Object>和全局变量数据的传递(Parcelable Serializable)
转http://blog.csdn.net/pku_android/article/details/7456305 一.传递List<String>和List<Integer> ...
- Android学习笔记_19_广播接收者 BroadcastReceiver及其应用_窃听短信_拦截外拨电话
一.广播接收者类型: 广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”. 普通广播是完全异步的,可以在同一时刻(逻辑上 ...
- HDU 1155 Bungee Jumping(物理题,动能公式,弹性势能公式,重力势能公式)
传送门: Bungee Jumping Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- postman发送HTTP请求自动生成MD5签名
POSTMAN是常用的接口测试工具 如何进行MD5签名呢? 代码如下: /** * 通过request.data获取body的内容,这个是postman内置变量 * 常用内置参数如下: * reque ...