当前位置:首页 > Cookie详解
用户每发起一次新的请求,浏览器在检查完本地存储 Cookie 的有效性后,会把所有由 MTS 产生的有效 Cookie 附加在请求头里送到 MTS。MTS 接受到客户端的翻译请求后,从 Request 中提取出所有的 Cookie,还原后根据目标服务器的 domain 和 path 进行过滤。产生所有与目标服务器相关的 Cookie。 接下来,需要把 Cookie 送到目标服务器中。我们使用 HTTPClient 与目标服务器连接。HTTPClient 在与目标服务器连接以后,允许服务器设置 Cookie 并在需要的时候自动将 Cookie 返回服务器,也支持手工设置 Cookie 后发送到服务器端。但是,由于如何处理 cookie 有几个规范互相冲突:Netscape Cookie 草案、RFC2109、RFC2965,而且还有很大数量的软件商的 Cookie 实现不遵循任何规范。 为了处理这种状况,需要把 HttpClient 设置成 Cookie 兼容模式,这样可以最大限度的处理好各种 Cookie。下面的代码把 Cookie 送到目标服务器。 MTS 把请求和 Cookie 送出后,继续接收目标服务器的应答,读取返回的原始 Cookie,并转换成可以存储在用户浏览器端的 Cookie。下面的代码将对原始 Cookie 的内容进行变换,保留 expires 和 secure 等项,把 domain 和 path 项编码到 name 中去。
最后一步,把这些 Cookie 保存到 response 里,随 HTTP 应答头返回用户浏览器。并保存在浏览器中。
至此,我们已经完成了接收用户请求,转换 Cookie,发送到目标服务器,接收目标服务器的原始 Cookie,并保存在客户浏览器的整个处理过程。
关于 Session 的考虑
在研究完如何管理和传递 Cookie 之后,我们也需要研究一下 Session 的传递。因为目前大部分站点都在采用 Session 机制保存用户状态数据,如果不能解决 Session 的传递问题,HTTP 应用代理服务器的适用范围同样会大打折扣。 首先我们了解一下 Session 的实现机制。Session 是一种服务器端的机制,服务器使用一种类似于散列表的结构来保存信息。当程序需要为某个客户端的请求创建一个 session 的时候,服务器首先检查这个客户端的请求里是否已包含了一个 session 标识 - 称为 session id,如果已包含一个 session id 则说明以前已经为此客户端创建过 session,服务器就按照 session id 把这个 session 检索出来使用(如果检索不到,可能会新建一个),session id 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串。
保存这个 session id 的方式之一就是采用 Cookie。一般这个 Cookie 的名字都类似于 SESSIONID。比如 WebSphere 对于 Web 应用程序生成的 Cookie:JSESSIONID= 0001HWF4iVD94pY8Cpbx6U4CXkf:10lro0398,它的名字就是 JSESSIONID。
保存 session id 的其他方式还包括 URL 重写和表单隐藏字段。这两种方式都不需要代理服务器作特殊处理。因此实际上,我们解决了 Cookie 的管理和传递的问题之后,也就解决了 Session 的管理和传递。
Cookie 的规范介绍
目前有以下几种 Cookie 规范:
Netscape cookie 草案:是最早的 cookie 规范,基于 rfc2109。尽管这个规范与 rc2109 有较大的差别,但是很多服务器都与之兼容。
? rfc2109, 是 w3c 发布的第一个官方 cookie 规范。理论上讲,所有的服务器在处理 cookie( 版本 1) 时,都要遵循此规范。遗憾的是,这个规范太严格了,以致很多服务器不正确的实施了该规范或仍在使用 Netscape 规范。
? rfc2965 规范定义了 cookie 版本 2,并说明了 cookie 版本 1 的不足。
?
rfc2965 规范的使用,目前并不多。rfc2109 规范相应要严格得多,在实际应用上,并不是所有的浏览器和 Web 服务器都严格遵守。因此相比较而言,Netscape cookie 草案倒是一个比较简洁和被广泛支持的 Cookie 规范,因此我们在这里以 Netscape cookie 草案为基础进行讨论,对于其他两种规范,我们的讨论和代码具有相同的意义。关于 Netscape cookie 草案的细节,大家可以参照 Netscape 官方站点,这里我们列举一些和我们讨论有关的内容。
根据 Netscape cookie 草案的描述,Cookie 是 Web 服务器向用户的浏览器发送的一段 ASCII 码文本。一旦收到 Cookie,浏览器会把 Cookie 的信息片断以\名 / 值\对 (name-value pairs) 的形式储存保存在本地。这以后,每当向同一个 Web 服务器请求一个新的文档时,Web 浏览器都会发送之站点以前存储在本地的 Cookie。创建 Cookie 的最初目的是想让 Web 服务器能够通过多个 HTTP 请求追踪客户。有些复杂的网络应用需要在不同的网页之间保持一致,它们需要这种会话状态的保持能力。
浏览器与 Web 服务器通过 HTTP 协议进行通讯,而 Cookie 就是保存在 HTTP 协议的请求或者应答头部(在 HTTP 协议中,数据包括两部分,一部分是头部,由一些名值对构成,用来描述要被传输数据的一些信息。一部分是主体 (body),是真正的数据(如 HTML 页面等))进行传送的。
在 HTML 文档被发送之前,Web 服务器通过传送 HTTP 包头中的 Set-Cookie 消息把一个 cookie 发送到用户的浏览器中。下面是一个遵循 Netscape cookie 草案的完整的 Set-Cookie 头:
Set-Cookie:customer=huangxp; path=/foo; domain=.ibm.com; expires= Wednesday, 19-OCT-05 23:12:40 GMT; [secure]
Set-Cookie 的每个属性解释如下:
? ?
?
?
?
Customer=huangxp 一个\名称=值\对,把名称 customer 设置为值\,这个属性在 Cookie 中必须有。
path=/foo 控制哪些访问能够触发 cookie 的发送。如果没有指定 path,cookie 会在所有对此站点的 HTTP 传送时发送。如果 path=/directory,只有访问 /directory 下面的网页时,cookie 才被发送。在这个例子中,用户在访问目录 /foo 下的内容时,浏览器将发送此 cookie。如果指定了 path,但是 path 与当前访问的 url 不符,则此 cookie 将被忽略。 domain=.ibm.com 指定 cookie 被发送到哪台计算机上。正常情况下,cookie 只被送回最初向用户发送 cookie 的计算机。在这个例子中,cookie 会被发送到任何在 .ibm.com 域中的主机。如果 domain 被设为空,domain 就被设置为和提供 cookie 的 Web 服务器相同。如果 domain 不为空,并且它的值又和提供 cookie 的 Web 服务器域名不符,这个 Cookie 将被忽略。
expires= Wednesday, 19-OCT-05 23:12:40 GMT 指定 cookie 失效的时间。如果没有指定失效时间,这个 cookie 就不会被写入计算机的硬盘上,并且只持续到这次会话结束。
secure 如果 secure 这个词被作为 Set-Cookie 头的一部分,那么 cookie 只能通过安全通道传输(目前即 SSL 通道)。否则,浏览器将忽略此 Cookie。
一旦浏览器接收了 cookie,这个 cookie 和对远端 Web 服务器的连续请求将一起被浏览器发送。例如 前一个 cookie 被存入浏览器并且浏览器试图请求 URL http://www.ibm.com/foo/index.html 时,下面的 HTTP 包头就被发送到远端的 Web 服务器。
GET /foo/index.html HTTP/1.0 Cookie:customer=huangxp 回页首
一次典型的网络浏览过程
在了解了 Cookie 协议的一些基本内容之后,让我们看看一次典型的网络浏览过程中浏览器如何识别和处理 Cookie:
浏览器对于 Web 服务器应答包头中 Cookie 的操作步骤: 1. 从 Web 服务器的应答包头中提取所有的 cookie。
2. 解析这些 cookie 的组成部分(名称,值,路径等等)。 3. 判定主机是否允许设置这些 cookie。允许的话,则把这些 Cookie 存储在本地。
? 浏览器对 Web 服务器请求包头中所有的 Cookie 进行筛选的步骤: 1. 根据请求的 URL 和本地存储 cookie 的属性,判断那些 Cookie 能被发送给 Web 服务器。
2. 对于多个 cookie,判定发送的顺序。
3. 把需要发送的 Cookie 加入到请求 HTTP 包头中一起发送。
?
回页首
由 MTS 代理的网络浏览过程
以上我们了解了在一个典型的浏览器与 Web 服务器交互的时候,Cookie 的传递过程。下面我们将看到,如果在 MTS 代理网络浏览的过程中,不对 Cookie 进行修改,上面的 Cookie 传递过程将无法实现。
1. 假设用户希望把 http://www.ibm.com/foo/index.html 页面翻译成法文,应该使用如下的 url 对 MTS 发出请求 :
http://www.mts.com/translate?url=http://www.ibm.com/foo/index.html&language=French
2. MTS 接收用户的请求,连接远程目标服务器
http://www.ibm.com/foo/index.html。目标服务器做出应答,返回 HTTP 头和 HTML 页面内容。其中,典型的 HTTP 头内容如下:
HTTP/1.1 200 OK
Date: Mon, 24 Oct 2005 06:54:41 GMT Server: IBM_HTTP_Server Cache-Control: no-cache Content-Length: 19885 Connection: close
Set-Cookie:customer=huangxp; path=/foo; domain=.ibm.com; expires= Wednesday, 19-OCT-05 23:12:40 GMT Content-Type: text/html
共分享92篇相关文档