当前位置: 首页 > 科技观察

这篇文章彻底理解了为什么cookies和session

时间:2023-03-19 14:49:00 科技观察

需要cookies和session。在Web发展史上,我们知道浏览器和服务器之间使用的是http协议,而这个协议是无状态的,所以这就导致服务器无法知道谁在浏览网页,但是显然,有些网页需要知道用户的状态,比如登录,购物车等。所以为了解决这个问题,相继出现了四种技术,分别是隐藏表单域,URL重写,cookie,session,还有用的最多也比较重要的一个是cookie和session。什么是饼干?Cookie是浏览器保存在用户计算机上的一小段文本。一般来说,当用户通过http访问服务器时,服务器会返回一些Key/Value键值对给客户端浏览器,并对这些数据进行一些限制。当条件满足,用户下次访问服务器时,数据会通过请求头完整的带回服务器,服务器根据这些信息判断不同的用户。换句话说,cookie是服务器传送给客户端并保存在客户端的一段信息。这个cookie有大小和数量限制!!cookie目前有两个版本,分别对应两个设置响应头:“Set-Cookie”和“Set-Cookie2”。Set-Cookie2在Servlet中是不支持的,所以我们先看一下Set-Cookie的属性项:这些属性项,其他的都很清楚了,再看看Domain有什么用:现在,我们假设有两个domainnames:域名A:a.b.f.com.cn域名B:c.d.f.com.cn显然,域名A和域名B都是f.com.cn的子域名如果我们将域名A中cookie的域设置为f.com.cn,那么f.com.cn及其子域都可以获得这个cookie,即域名A和域名B都可以获得这个cookie。覆盖发生如果域名A没有显式设置Cookie的域方法,则域为a.b.f.com.cn。不同的是,此时域名A的子域名将无法获取到这个cookie。好了,现在你已经理解完Set-Cookie属性项,开始创建CookieWeb服务器通过发送一个名为Set-Cookie:Set-Cookie:value[;的http消息来创建一个Cookie。过期=日期][;域=域][;路径=路径][;secure]这里我们思考一个问题,当我们在服务器上创建多个cookie时,这些cookie最终是在一个Header项中,还是作为一个独立的Header?我们可以看到,在构造HTTP返回字节流时,是将Header中的所有项按顺序写出来,不做任何修改。所以可以想象,当浏览器收到http返回的数据时,会分别解析每一个Header项。那么,在客户端保存,怎么保存呢?这里我们需要进一步了解cookies的分类。会话级cookie:所谓会话级cookie,是指cookie在浏览器关闭后即失效。持久级cookie:保存在硬盘上的cookie,只要设置了过期时间,就是硬盘级cookie。好了,现在cookie保存在客户端了。当我们请求一个URL时,浏览器会根据URL路径在请求头中将符合条件的cookie发送给服务器。SessionCookie是有大小和数量限制的,越来越多的cookie代表着客户端和服务端之间传输量的增加。能不能每次都传所有的cookie值,只传一个唯一的ID,通过这个ID直接在服务器上查找用户信息呢?答案是肯定的,这是我们的会议。会话基于cookie工作。同一个客户端每次访问服务器,只要浏览器第一次访问服务器,服务器都会设置一个id,保存一些信息(比如登录时保存用户信息,视具体情况而定),并将这个id通过cookie保存到客户端,客户端每次与服务器交互时只传递这个id,从而维护浏览器和服务器的状态,这个id通常是一个cookie,名称为JSESSIONID。其实有四种方法可以让Session正常工作:通过URL传递SessionID通过Cookie传递SessionID通过SSL传递SessionID通过隐藏形式传递SessionID第一种情况:当浏览器不支持Cookie功能时,浏览器会通过用户的SessionCookieName(默认为JSESSIONID)被重写为用户请求的URL参数。格式:/path/Servlet;name=value;name2=value2?name3=value3第三种情况:SessionID会根据javax.servlet.request.ssl_session属性值来设置。注意:如果客户端支持cookie并重写了URL,Tomcat仍然会解析cookie中的SessionID并覆盖URL中的SessionID通过request.getSession()方法为这个客户端创建一个Session。如果当前SessionID没有对应的HttpSession对象,则新建一个添加到org.apache.catalina.Manager的session容器中保存。这是完成了维护状态的时候了。当然,这个SessionID是唯一的。2.Session存储从图中可以看出,Session对象已经存储在Manager类中,StandardManager作为实现类。StandardSession对象通过requestedSessionId从StandardManager的会话集合中获取。让我们看看StandardManager是如何管理所有StandardSession对象的生命周期的。Servlet容器关闭时:当Servlet容器重启时,StandardManager会持久化未过期的StandardSession对象(必须调用Servlet容器中的stop和start命令,不能直接kill)。:StandardManager初始化时会重新读取这个文件并解析出所有的会话对象。3、session的销毁这里有个误区,也是我之前的一个误区,就是我把session的生命周期理解为session,打开浏览器时创建,关闭浏览器时销毁。这个理解是错误的!!session语句的周期是从创建到超时到期。也就是说,当session创建时,浏览器关闭,session级cookie被销毁。如果没有超过设定的时间,则不销毁该SessionID对应的会话。检查session失效检查每个Session是否无效是在Tomcat的一个后台线程中完成的(backgroundProcess()方法);调用request.getSession()除了后台进程检查session是否失效外,还会检查session是否过期。当然,调用这个方法过期的话,会重新创建一个新的session。总结一下两者的异同点(有关联的地方):Session和Cookie都是为了让http协议有状态而存在的。Session是通过Cookie来工作的,通过Cookie传递的SessionID让Session知道客户端是谁。区别:Session将信息保存到服务器端,而Cookie将信息保存在客户端。工作流程当浏览器第一次访问服务器时,服务器会创建一个Session,并将SessionID通过Cookie带给浏览器保存在客户端。同时服务端根据业务逻辑保存对应的客户端。终端信息保存在session中;客户端再次访问时上传cookie,服务端拿到cookie后获取里面的SessionID来保持状态。