cookie和session的区别及其原理
1.为什么要有cookie/session?
- HTTP是一种无状态的协议,为了分辨链接是谁发起的,需自己去解决这个问题。不然有些情况下即使是同一个网站每打开一个页面也都要登录一下。而Session和Cookie就是为解决这个问题而提出来的两个机制。
2.cookie/session执行流程
cookie执行流程
当你去访问服务器的时候,服务器如果想让浏览器保存点数据,这时服务器就产生一个键值对的数据(new cookie),把数据带到浏览器,浏览器会将次数据保存起来。(其底层就是通过一叫做set-cookie的响应头来实现的)。接下来当再次去访问服务器时候,浏览器会根据一定的规则将cookie带上(底层就是一个叫做cookie的请求头),这样在服务器端就可以通过方法获取这些数据.
Cookie的主要内容包括:名字,值,过期时间,路径和域(api 后面会讲)。使用Fiddler抓包就可以看见,比方说我们打开百度的某个网站可以看到Headers包括Cookie,如下:
key, value形式。过期时间可设置的,如不设,则浏览器关掉就消失了,存储在内存当中,否则就按设置的时间来存储在硬盘上的,过期后自动清除,比方说开关机关闭再打开浏览器后他都会还存在,前者称之为Session cookie 又叫 transient cookie(临时cookie),后者称之为Persistent cookie (持久化cookie)又叫 permenent cookie。路径和域就是对应的域名,a网站的cookie自然不能给b用。
session执行流程
客服端访问服务器,如果遇到了 getsession()方法。服务器会检查客户端是否携带了一个叫做JSESSIONID的cookie
没有携带
服务器在内存开辟一块空间(new session),同时会生成一个随机的唯一的字符串,将随机的字符串跟创建session对象关联起来( key->字符串,value->session对象)
放入在session池中,放回到客户端的时候,服务器会将字符串包装一下,new cookie("JSESSIONID",字符串),带回去给客户端
有携带:
将此cookie的中的值取出来,字符串取出来,把他当做key去session池中查找对应的session对象
找到了
根据业务逻辑操作session对象
没找到了
服务器在内存开辟一块空间(new session),同时会生成一个随机的唯一的字符串,将随机的字符串跟创建session对象关联起来放入在session池中( key->字符串,value->session对象),放回的时候,服务器会将字符串包装一下,new cookie("JSESSIONID",字符串),带回去给浏览器
sesion
存在服务器的一种用来存放用户数据的类HashTable结构。
浏览器第一次发送请求时,服务器自动生成了一HashTable和一Session ID来唯一标识这个HashTable,并将其通过响应发送到浏览器。浏览器第二次发送请求会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的HashTable。
一般这个值会有个时间限制,超时后毁掉这个值,默认30分钟。
当用户在应用程序的 Web页间跳转时,存储在 Session 对象中的变量不会丢失而是在整个用户会话中一直存在下去。
Session的实现方式和Cookie有一定关系。建立一个连接就生成一个session id,打开几个页面就好几个了,这里就用到了Cookie,把session id存在Cookie中,每次访问的时候将Session id带过去就可以识别了.
3.cookie的常用属性api
Cookie cookie = new Cookie("name","tom"); // 新建Cookie
cookie就是键值对的数据,如果是中文不能直接设置,需要编码
Cookie cookie3 = new Cookie("realname",URLEncoder.encode("姓名","utf-8"));
cookie.setDomain("www.baidu.com"); // 设置域名
这样设置域名的话,该cookie会被提交到www.baidu.com但是不会被提交到zhidao.baidu.com。要想都提交过去,需要这样设置cookie.setDomain(".baidu.com");
cookie.setPath("/search"); // 设置路径
这样设置路径,该cookie只会被提交到www.baidu.com/search路径下的页面,也就是说在www.baidu.com/aaa下的页面是获取不到该cookie的。一般cookie在某个网站里都是可用的,直接设置为/,cookie.setPath("/");
cookie.setMaxAge(60*60*24*7); // 设置有效期
MaxAge属性单位为秒,默认为-1也就是关闭浏览器自动销毁(临时cookie)。cookie.setMaxAge(60*60*24*7); 这样设置意思是不管浏览器关闭与否,将此cookie持久化到客户端文件里保存一周。参数为正数时浏览器都会将相应的cookie做持久化处理。
response.addCookie(cookie); // 输出到客户端
4.session常用api
HttpSession session = request.getSession(); // 创建session
session.setAttribute("name","tom"); // 设置Session属性
out.println("欢迎您:" +session.getAttribute("name")); // 获取Session属性
销毁session ServletActionContext.getRequest().getSession().invalidate();
通过java代码设置
session.setMaxInactiveInterval(30*60);//以秒为单位,即在没有活动30分钟后,session将失效
在tomcat配置文件中配置session的超时时间
<session-config>
<session-timeout>分钟为单位</session-timeout>
</session-config>
5cookie/session的区别与联系区别:
1.cookie存放在客户端,session存放在服务器端。
2.cookie只能存放4k的数据,而session理论上没有做限制
联系:
session虽说存放在服务器端,但是仔细看刚才的执行流程你会明白,session是依赖于cookie的,这一点也是本篇文章想要着重强调的
7.cookie/session使用注意事项
1.cookie大小有限制 4k
2.cookie不能跨浏览器
3.cookie默认不支持中文(但是可以通过转码)
4.cookie对于浏览器 一个浏览器中最多可以保存300cookie 为每个网站最多20个
5.如果是安全性较高的数据应存放在session中,因为cookie存放在客户端总会轻易被不法分子获取
6.如果是访问量特别大的网站,尽量不要在session中存储用户数据,因为每个用户存一个session会给服务器造成很大的压力
7.cookie 创建默认是临时cookie 就是浏览器关闭,cookes失效,而seesion创建默认是30分钟, cookie 和seesion 都可以持久化(设置时间)。
8.session 的使用是依赖cookie的 应为session的唯一标示sessionID 放在cookie中,下面会讲下工作遇到的坑。
6.新手使用session时常踩的坑
很多人使用session时希望用户信息可以保存一段时间比如保存7天,于是配置了Tomcat的
<session-config>
<session-timeout>7天</session-timeout>
</session-config>。
配置完后发现,关闭浏览器后再访问还是取不到session。这是因为session的配置没起作用吗?不是的,其实session还是存在于服务器的,只是没有设置cookie持久化,cookie默认就会在浏览器关闭时销毁,所以叫做JSESSIONID的cookie也被销毁了,再到服务器的时候没有这个叫JSESSIONID的cookie就取不到相关的session了。
所以,如果想7天内都能访问到session,需要将cookie也设置持久化!