nState cookieless="true" />
ASP.NET 会话状态的默认设置是在 machine.config 文件中定义的,并且可以在应用程序根文件夹中的 web.config 文件中重写。通过确保上述行出现在根 web.config 文件中,您可以启用无 Cookie 会话。就是这样 — 简单而有效!
<sessionState>节点还可以用于配置会话状态管理的其他方面,包括存储介质和连接字符串。但是,就 Cookie 而言,只需您将 cookieless 属性设置为 true(默认设置为 false)。
请注意,会话设置是应用程序范围的设置。换句话说,您站点中的页要么都将使用要么都将不使用 Cookie 来存储会话 ID。
当不使用 Cookie 时,ASP.NET 在哪里存储会话 ID 呢?在这种情况下,会话 ID 插入到 URL 内的特定位置中。下图显示一个使用无 Cookie 会话的真实站点的快照。
图 1. 使用无 Cookie 会话的 MapPoint
假设您请求了一个类似于 http://yourserver/folder/default.aspx 的页。正如您可以从 MapPoint 快照中看到的那样,资源名称前面的相邻斜杠进行了扩展,以便包含在内部填充了会话 ID 的括号,如下所示。
http://yourserver/folder/(session ID here)/default.aspx
会话 ID 嵌入到 URL 中,并且无需在其他任何地方持久保存它。唔,并不完全是这样。请考虑以下方案。
您访问了一个页,并且被分配了一个会话 ID。接下来,您清除了同一浏览器示例的地址栏,转到另一个应用程序并且开始工作。然后,您重新键入了上一个应用程序的 URL,并且(猜猜看)在您进入的过程中检索会话值。
如果您使用无 Cookie 会话,那么当您第二次访问该应用程序时,您将被分配一个不同的会话 ID,并且丢失以前的所有状态。这是无 Cookie 会话的一个典型的副作用。为了了解其原因,让我们进一步探讨无 Cookie 会话的实现。
返回页首
实现
无 Cookie 会话的实现得益于下列两个运行时模块的努力:一个名为 SessionStateModule 的标准会话 HTTP 模块,以及一个名为 aspnet_filter.dll 的可执行文件。后者是一小段 Win32 代码,它充当 ISAPI 筛选器。HTTP 模块和 ISAPI 筛选器实现了相同的思想,不同之处在于 HTTP 模块由托管代码组成,并且需要 ASP.NET 和 CLR 触发才能工作。像 aspnet_filter.dll 这样的传统 ISAPI 筛选器是由 Internet 信息服务 (IIS) 调用的。二者都截获在请求处理过程中激发的 IIS 事件。
当新浏览器会话的第一个请求进入时,会话状态模块读取 web.config 文件中有关 Cookie 支持的设置。如果 节的 cookieless 属性设置为 true,则该模块生成一个新的会话 ID,通过将该会话 ID 填充到资源名称前面的相邻位置来分割 URL,并且使用 HTTP 302 命令将浏览器重定向到新的 URL。
当每个请求到达 IIS 入口时(远远早于它被移交给 ASP.NET),aspnet_filter.dll 获得了一个查看它的机会。如果该 URL 将会话 ID 嵌入到括号中,则会提取该会话 ID 并将其复制到一个名为 AspFilterSessionId 的请求标头中。然后,重写该 URL 以使其看起来像原来请求的资源,并且将其释放。这一次,ASP.NET 会话状态模块从请求标头中检索会话 ID,并且通过会话-状态绑定继续工作。
只要该 URL 包含可用来获取会话 ID 的信息,无 Cookie 机制就可以很好地工作。正如您稍后将看到的那样,这会造成一些使用限制。
让我们研究一下无 Cookie 会话的优缺点。
返回页首
优点
在 ASP.NET 中,会话管理和表单身份验证是唯一的两个在后台使用 Cookie 的系统功能。通过无 Cookie 会话,您现在可以部署无论用户的有关 Cookie 的首选项如何都能正常工作的有状态应用程序。然而,就 ASP.NET 1.x 而言,仍然需要使用 Cookie 来实现表单身份验证。好消息是,在 ASP.NET 2.0 中,表单身份验证可以选择以无 Cookie 方式工作。
另一个经常