目录
1.什么是HTTP?
3.session
如果你对于session 和cookie 只有一点模糊理解,那么此文章能帮你更深入理解session和cookie ,依旧和上篇文章一样,我们采用问题的方式来一步步探索,这篇文章会告诉你这些:
为什么要有session 和cookie
session 和cookie它们是如何工作的?
session和cookie 它们有什么联系,又有什么区别?
为什么要有session和cookie?
session 和cookie 为什么会出现那么我们只能问http了,http创建这两个东西又是为什么呢?所以我们首先得了解一下这个http;
Http协议即超文本传送协议 (HTTP-Hypertext transfer protocol) ,它是基于 TCP/IP 协议的应用层协议。它不涉及数据包传输,主要规定了客户端和服务器之间的通信格式。
简单的说,http 是互联网请求数据传输的一种规范,它规定了客户端与服务器之间互相通信的数据格式规则。它是基于TCP/IP协议之上的应用层协议,这就好像球类运动(TCP/IP)和足球(HTTP)的关系,在球类运动里规定一个只能用脚踢的球类运动规则,这类规则形成的运动名字就叫足球。
HTTP 协议一共有几个特点:支持客户/服务器模式;简单快速;灵活;无连接,无状态。其中HTTP无状态的特性将和我们今天的主题有密切关系。
上面http的特点提到了无状态,那么http的无状态是什么意思呢?
http 是一种无状态的协议,”无状态”其实这种描述有点模糊,这里的无状态更精确的说法应该是”不保存请求的状态信息”的意思,http要做的事就是规范WEB数据传输格式,协议本身不会对请求和响应的通信状态进行保存。
至于http什么要这么做,主要有下面几个原因:
1、职责单一化:既然我是个协数据传输协议,那么我就只做协议层需要做的事情,保存临时请求状态类的信息那是缓存的功能。
2、方便扩展:只有把一件事情做的越简单,那么它的伸缩性才越好,
比如:如果你是生产自来水的,那你安安心心只生产自来水就行了,这样的话那些生产任何饮料的都可以从你这里进货,只要需要自来水的地方都可以和你合作。但是结果你为了水的味道好一点,在水里面加了一点糖,这样就会造成做茶类的饮料没办法和你合作了,因为茶里面是不需要加糖的。
3、提升效率:不需要保存额外的信息请求的速度当然要快一些。
那么http的无状态会带来什么问题吗?
因为http是不保存状态信息的,所以这就意味着两次请求之间是没办法建立联系,这就造成了前一个请求已经做过的事情,后面的请求还是照样要做一次。
比如我们最常见的系统功能”登录验证”:
我们系统很多功能都需要进行登录才可以操作,比如说,查看个人信息、下单、加好友.........等等;
这里如果我们不保存用户登录的状态信息,那么我每次查看个人信息之前都需要先进行登录,然后才能查看到个人信息,那么多个请求就会以这样的形式体现出来。
查看个人信息请求:登录=>查看个人信息
下单请求: 登录=>下单
加好友请求: 登录=>发送好友申请
当你看到上面的请求执行情况,你应该就发现了问题,明显登录其实只要做一次就行了,那么我们是否可以在用户第一次登录后就把用户的登录状态保存起来呢,以后的请求只需要通过这个状态来判断用户是否有进行登录,那么是否就能避免用户需要重复的登录呢? 所以就出现了我们的http状态保持方案,cookie 和session;
cookie是把请求状态存储在客户端的一种解决方案;因为http的无状态,我们无法识别历史请求的状态信息,所以就想出了一个办法,服务端会在每个客户端第一次请求的时候颁发一个通行证,不管服务端和客户端都可以往这个通信证里存入状态信息,然后交由客户端保存,客户端以后每次向服务器发起请求的时候都会带上这个通行证,通过在这种方式来保持请求之间的联系。
java操作cookie如下:
//获取cookie
Cookie[] cookies= request.getCookies();
//添加cookie
Cookie cookie=new Cookie("name","susan");
//设置有效时间(秒)
cookie.setMaxAge(1000);
//当请求是HTTPS或者其他安全协议时才传输cookie
cookie.setSecure(true);
//设置cookie是否能通过 js 访问
cookie.setHttpOnly(true);
//设置cookie作用域 doman+path形成一个cookie作用范围
cookie.setDomain("http://baidu.com");
cookie.setPath("/user");
response.addCookie(cookie);
删除cookie
主动设置有效期删除
Cookie并没有提供直接删除的方法,我们只能通过setMaxAge(-1)设置有效期来简介达到删除cookie的效果。
持久cookie: 如果通过setMaxAge设置了cookie的有效期时间大于0,则浏览器会把该cookie持久化到磁盘,然后根据设置的时间判断过期则失效。
临时cookie:当通过setMaxAge设置cookie的有效时间为负数,此时的cookie就属于一个临时cookie,临时cookie只会保存在客户端内存里面,当浏览器关闭后就会失效。
session是把状态信息保存在服务端的一种解决方案,那么为什么有了Cookie之后还需要有seesion呢,其实我们在了解cookie的特点后知道我们的cookie是存储在客户端的,所以会存在一些不可控的问题,比如说cookie可以被窃取,而且cookie的大小也被客户端所限制,所以会存在一些不安全的因素,所以那就只能把状态信息保存到服务端,交给服务端自己控制,而session则就是服务端保持状态的解决方案。
那么问题出现了,session是如何生成的呢?
当客户端(浏览器)访问服务端时服务端首先会读取cookie;
如果cookie里面包含一个JSESSIONID的值,那么服务端会根据对应的JSESSIONID 从内存里面获取对应的session。
如果cookie 没有JSESSIONID 那么服务端会认为这是用户第一次访问,那么就会新生成一个session保存到内存里面,然后把session的唯一ID添加到cookie里面,就键的名称就是我们上面的JSESSIONID。
服务端生成session并把seesion的ID添加到cookie里面后,客户端每次请求访问都会带上cookie。
Session是如何删除的?
1、服务端可以设置session的超时时间,session超时后会被删除。
2、调用HttpSession.invalidate()方法删除sesion。
3、服务器进程停止。
如果当cookie被禁用该如何使用session呢?
我们从session使用流程中可以知道,其实session虽然是服务端保存的,但是也还是需要客户端的配合才能使用,而这个配合通常都是cookie来保存session的sesion ID,然后客户端每次都带上cookie,服务端通过sesion ID来识别客户端的身份。
但是这样有一个问题,我们知道客户端是可以禁用cookie的,如果客户端禁用了cookie后我们如何传递这个session ID呢。
如果cookie禁用后,我们通常可以通过URL重写和增加隐藏字段的方式来传输session ID,其原理就是在客户端所有请求里面都添加一个JSESSIONID的参数,服务端再通过获取这个参数来识别客户端的请求。这种方式虽然能解决sesion ID 传递的问题,但是在存在一些问题,所以很少使用。
cookie的数据信息存放在本地(客户端)。
session的数据信息存放在服务器上。
cookie存储的容量较小,一般<=4KB。
session存储容量大小没有限制(但是为了服务器性能考虑,一般不能存放太多数据)。
cookie可以长期存储,只要不超过设置的过期时间,可以一直存储。
session在超过一定的操作时间(通常为30分钟)后会失效,但是当关闭浏览器时,为了保护用户信息,会自动调用session.invalidate()方法,该方法会清除掉session中的信息。
cookie存储在客户端,所以可以分析存放在本地的cookie并进行cookie欺骗,安全性较低。
session存储在服务器上,不存在敏感信息泄漏的风险,安全性较高。
cookie支持跨域名访问。例如,所有a.com的cookie在a.com下都能用。
session不支持跨域名访问。例如,www.a.com的session在api.a.com下不能用。
cookie保存在客户端,不占用服务器资源。
session是保存在服务器端,每个用户都会产生一个session,session过多的时候会消耗服务器资源,所以大型网站会有专门的session服务器。
cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。
session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。