您现于de位置乃:亚博 > APP基础

亚博 2017-05-25 APP基础 1652

sessionde工作原理详细分析

sessionde工作原理
1 术语session 
于我de经验里 session这个词被滥用de程度大概仅次于transaction 更加有趣de乃transaction与session于某些语境下de含义乃相同de. 

session 中文经常翻译为会话 其本来de含义乃指有始有终de1系列动作/消息 比如打电话时从拿起电话拨号到挂断电话这中间de1系列过程可以称之为1个session.有时候我们可以看到这样de话"于1个浏览器会话期间 ..." 这里de会话1词用de就乃其本义 乃指从1个浏览器窗口打开到关闭这个期间①.最混乱de乃"用户(客户端)于1次会话期间"这样1句话 它可能指用户de1系列动作(1般情况下乃同某个具体目de相关de1系列动作 比如从登录到选购商品到结账登出这样1个网上购物de过程 有时候也被称为1个transaction) 然而有时候也可能仅仅乃指1次连接 也有可能乃指含义① 其中de差别只能靠上下文来推断②. 

然而当session1词与网络协议相关联时 它又往往隐含了"面向连接"和/或"保持状态"这样两个含义 "面向连接"指de乃于通信双方于通信之前要先建立1个通信de渠道 比如打电话 直到对方接了电话通信才能开始 与此相对de乃写信 于您把信发出去de时候您并不能确认对方de地址乃否正确 通信渠道不1定能建立 但对发信人来说 通信已经开始了."保持状态"则乃指通信de1方能够把1系列de消息关联起来 使得消息之间可以互相依赖 比如1个服务员能够认出再次光临de老顾客并且记得上次这个顾客还欠店里1块钱.这1类de例子有"1个TCP session"或者"1个POP3 session"③. 

而到了web服务器蓬勃发展de时代 session于web开发语境下de语义又有了新de扩展 它de含义乃指1类用来于客户端与服务器之间保持状态de解决方案④.有时候session也用来指这种解决方案de存储结构 如"把xxx保存于session里"⑤.由于各种用于web开发de语言于1定程度上都提供了对这种解决方案de支持 所以于某种特定语言de语境下 session也被用来指代该语言de解决方案 比如经常把Java里提供dejavax.servlet.http.HttpSession简称为session⑥. 

鉴于这种混乱已不可改变 本文中session1词de运用也会根据上下文有不同de含义 请大家注意分辨. 
于本文中 使用中文"浏览器会话期间"来表达含义① 使用"session机制"来表达含义④ 使用"session"表达含义⑤ 使用具体de"HttpSession"来表达含义⑥ 

2 HTTP协议与状态保持 
HTTP协议本身乃无状态de 这与HTTP协议本来de目de乃相符de 客户端只需要简单de向服务器请求下载某些文件 无论乃客户端还乃服务器都没有必要纪录彼此过去de行为 每1次请求之间都乃独立de 好比1个顾客和1个自动售货机或者1个普通de(非会员制)大卖场之间de关系1样. 

然而聪明(或者贪心?)de人们很快发现如果能够提供1些按需生成de动态信息会使web变得更加有用 就像给有线电视加上点播功能1样.这种需求1方面迫使HTML逐步添加了表单 脚本 DOM等客户端行为 另1方面于服务器端则出现了CGI规范以响应客户端de动态请求 作为传输载体deHTTP协议也添加了文件上载 cookie这些特性.其中cookiede作用就乃为了解决HTTP协议无状态de缺陷所作出de努力.至于后来出现desession机制则乃又1种于客户端与服务器之间保持状态de解决方案. 

让我们用几个例子来描述1下cookie和session机制之间de区别与联系.笔者曾经常去de1家咖啡店有喝5杯咖啡免费赠1杯咖啡de优惠 然而1次性消费5杯咖啡de机会微乎其微 这时就需要某种方式来纪录某位顾客de消费数量.想象1下其实也无外乎下面de几种方案: 
1 该店de店员很厉害 能记住每位顾客de消费数量 只要顾客1走进咖啡店 店员就知道该怎么对待了.这种做法就乃协议本身支持状态. 
2 发给顾客1张卡片 上面记录着消费de数量 1般还有个有效期限.每次消费时 如果顾客出示这张卡片 则此次消费就会与以前或以后de消费相联系起来.这种做法就乃于客户端保持状态. 
3 发给顾客1张会员卡 除了卡号之外什么信息也不纪录 每次消费时 如果顾客出示该卡片 则店员于店里de纪录本上找到这个卡号对应de纪录添加1些消费信息.这种做法就乃于服务器端保持状态. 

由于HTTP协议乃无状态de 而出于种种考虑也不希望使之成为有状态de 因此 后面两种方案就成为现实de选择.具体来说cookie机制采用de乃于客户端保持状态de方案 而session机制采用de乃于服务器端保持状态de方案.同时我们也看到 由于采用服务器端保持状态de方案于客户端也需要保存1个标识 所以session机制可能需要借助于cookie机制来达到保存标识de目de 但实际上它还有其他选择. 

3 理解cookie机制 
cookie机制de基本原理就如上面de例子1样简单 但乃还有几个问题需要解决:"会员卡"如何分发;"会员卡"de内容;以及客户如何使用"会员卡". 

正统decookie分发乃通过扩展HTTP协议来实现de 服务器通过于HTTPde响应头中加上1行特殊de指示以提示浏览器按照指示生成相应decookie.然而纯粹de客户端脚本如JavaScript或者VBScript也可以生成cookie. 

而cookiede使用乃由浏览器按照1定de原则于后台自动发送给服务器de.浏览器检查所有存储decookie 如果某个cookie所声明de作用范围大于等于将要请求de资源所于de位置 则把该cookie附于请求资源deHTTP请求头上发送给服务器.意思乃麦当劳de会员卡只能于麦当劳de店里出示 如果某家分店还发行了自己de会员卡 那么进这家店de时候除了要出示麦当劳de会员卡 还要出示这家店de会员卡. 

cookiede内容主要包括:名字 值 过期时间 路径和域. 
其中域可以指定某1个域比如.google.com 相当于总店招牌 比如宝洁公司 也可以指定1个域下de具体某台机器比如www.google.com或者froogle.google.com 可以用飘柔来做比. 
路径就乃跟于域名后面deURL路径 比如/或者/foo等等 可以用某飘柔专柜做比. 
路径与域合于1起就构成了cookiede作用范围. 
如果不设置过期时间 则表示这个cookiede生命期为浏览器会话期间 只要关闭浏览器窗口 cookie就消失了.这种生命期为浏览器会话期decookie被称为会话cookie.会话cookie1般不存储于硬盘上而乃保存于内存里 当然这种行为并不乃规范规定de.如果设置了过期时间 浏览器就会把cookie保存到硬盘上 关闭后再次打开浏览器 这些cookie仍然有效直到超过设定de过期时间. 

存储于硬盘上decookie可以于不同de浏览器进程间共享 比如两个IE窗口.而对于保存于内存里decookie 不同de浏览器有不同de处理方式.对于IE 于1个打开de窗口上按Ctrl-N(或者从文件菜单)打开de窗口可以与原窗口共享 而使用其他方式新开deIE进程则不能共享已经打开de窗口de内存cookie;对于Mozilla Firefox0.8 所有de进程和标签页都可以共享同样decookie.1般来说乃用javascriptdewindow.open打开de窗口会与原窗口共享内存cookie.浏览器对于会话cookiede这种只认cookie不认人de处理方式经常给采用session机制deweb应用程序开发者造成很大de困扰. 

下面就乃1个goolge设置cookiede响应头de例子 
HTTP/1.1 302 Found 
Location: http://www.google.com/intl/zh-CN/ 
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649M=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com 
Content-Type: text/html 

这乃使用HTTPLook这个HTTP Sniffer软件来俘获deHTTP通讯纪录de1部分 
浏览器于再次访问goolgede资源时自动向外发送cookie 
使用Firefox可以很容易de观察现有decookiede值 
使用HTTPLook配合Firefox可以很容易de理解cookiede工作原理. 
IE也可以设置于接受cookie前询问 
这乃1个询问接受cookiede对话框. 

4 理解session机制 
session机制乃1种服务器端de机制 服务器使用1种类似于散列表de结构(也可能就乃使用散列表)来保存信息. 

当程序需要为某个客户端de请求创建1个sessionde时候 服务器首先检查这个客户端de请求里乃否已包含了1个session标识 - 称为session id 如果已包含1个session id则说明以前已经为此客户端创建过session 服务器就按照session id把这个session检索出来使用(如果检索不到 可能会新建1个) 如果客户端请求不包含session id 则为此客户端创建1个session并且生成1个与此session相关联desession id session idde值应该乃1个既不会重复 又不容易被找到规律以仿造de字符串 这个session id将被于本次响应中返回给客户端保存. 

保存这个session idde方式可以采用cookie 这样于交互过程中浏览器可以自动de按照规则把这个标识发挥给服务器.1般这个cookiede名字都乃类似于SEEESIONID 而.比如weblogic对于web应用程序生成decookie JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 它de名字就乃JSESSIONID. 

由于cookie可以被人为de禁止 必须有其他机制以便于cookie被禁止时仍然能够把session id传递回服务器.经常被使用de1种技术叫做URL重写 就乃把session id直接附加于URL路径de后面 附加方式也有两种 1种乃作为URL路径de附加信息 表现形式为http://...../xxx;jsessionid=ByOK ... 99zWpBng!-145788764 
另1种乃作为查询字符串附加于URL后面 表现形式为http://...../xxx?jsessionid=ByOK ... 99zWpBng!-145788764 
这两种方式对于用户来说乃没有区别de 只乃服务器于解析de时候处理de方式不同 采用第1种方式也有利于把session idde信息和正常程序参数区分开来. 
为了于整个交互过程中始终保持状态 就必须于每个客户端可能请求de路径后面都包含这个session id. 

另1种技术叫做表单隐藏字段.就乃服务器会自动修改表单 添加1个隐藏字段 以便于表单提交时能够把session id传递回服务器.比如下面de表单 

评论