浅谈Cookie和Session
由于HTTP协议是一种无状态的协议,即客户端浏览器的每一次请求都是独立的,与之前和之后的请求都没有关系,都是相互独立的。这就意味着服务器中没有保存客户端浏览器的数据信息,使得客户端浏览器每一次请求都要带上自己的状态信息去访问服务器。
为了弥补HTTP协议的这一缺点,就有了Cookie和Session两种会话机制。
一、Cookie机制
当客户端浏览器访问服务器时,为了记录客户端浏览器的状态,服务器就为浏览器发送一个Cookie,用来记录浏览器的状态。客户端浏览器会将该Cookie保存下来,当下一次再访问浏览器时,会携带该Cookie提交给服务器,服务器会检查Cookie的内容来辨别用户的状态。
Java中把Cookie封装成了javax.servlet.http.Cookie类,每一个Cookie都是该类的一个对象。Cookie使用 key-value 的形式保存信息,一个Cookie保存一个属性值,客户端浏览器可以保存多个Cookie,服务器端可通过 request对象的 getCookies()方法获取Cookie,存放在数组中。
Cookie具有不可跨域名的性质,每一个服务器都会为不同的客户端浏览器发送属于自己的Cookie,又因为Cookie保存在客户端浏览器中,因此客户端浏览器能够保证每一个服务器去操作自己的Cookie。若网站的域名不一样依然无法互相操作Cookie。
Cookie只能保存ASSCII码,需要对 Unicode字符进行编码。
Cookie的有效期可以通过:cookie.setMaxAge(int maxAge) 方法进行设置。
该方法中 maxAge的单位为秒,若maxAge为正数,表示在maxAge秒之后,该Cookie失效;
若为负数,表示该Cookie为临时的,当关闭浏览器时,该Cookie失效;
默认值为-1;
可设置 maxAge = Integer.MAX_VALUE 表示永久保存Cookie;
由于Cookie机制中没有提供销毁的方法,可通过这只 maxAge=0 来删除Cookie。
注意:1、response对象中对于Cookie的操作方法只有添加的方法:resp.addCookie(Cookie cookie);
因此要想修改Cookie,只能通过创建同名的Cookie来覆盖原有的Cookie,已达到修改的目的。
2、客户端只能读取到 name和value属性,maxAge属性只能被客户端用来判断Cookie是否有效。
以下是一个服务器给客户端发送Cookie,保存上一次登录时间的例子:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//作者亲测,Chrome需要以下这样设置,解决中文乱码问题
req.setCharacterEncoding("UTF-16");
resp.setCharacterEncoding("UTF-16");
PrintWriter out = resp.getWriter();
//Cookie,服务器从客户端获取,
Cookie[] cookies = req.getCookies();
//判断Cookie是否存在
if(cookies != null){
out.write("您上次访问的时间为:");
for(int i=0;i<cookies.length;i++){
Cookie cookie = cookies[i];
//获取cookie的名字
if(cookie.getName().equals("lastLoginTime")){
//获取cookie中的值
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
}else{
out.write("这是您第一次访问小站: ");
}
//服务器给客户响应一个cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
//设置cookie有效期为一天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
二、Session机制
Session是存放在服务器端的,用来存放用户数据的,当用户第一次访问服务器时,服务器就自动生成一个Session,并且为其生成 Session ID来唯一标识该Session,并且将该ID发送给浏览器,当浏览器下一次访问服务器时需要将该ID一同发送给服务器,服务器通过对比ID号,找到该客户端浏览器对应的Session,这样就保证了当前客户端浏览器只能找到自己的Session。
为了提升存取的速度,服务器一般会把Session保存在内存中,因此Session的信息不能过于复杂,应尽量精简,以减轻服务器的压力。
Session生成后,只要用户访问服务器,服务器就会不断的更新Session的内容,并维护Session。
Session的ID保存有两种形式:1、使用Cookie的形式进行保存。服务器通过设置Cookie将ID发送给客户端浏览器,同时,还可设置Cookie的有效时间;
2、使用URL重写的方式,该方式主要应用于不支持Cookie的浏览器。将用户Session的ID重写到URL中,当再次访问服务器时,服务器通过解析URL获取ID。
以下是在Session中存取对象,获取ID的例子:
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
Person person = new Person("哈哈", 18, "男");
session.setAttribute("person",person);
//session.setAttribute("name","哈哈哈哈");
//获取Session的id
String sessionId = session.getId();
//判断Session是不是新创建的
if(session.isNew()){
resp.getWriter().write("Session创建成功,ID为:" + sessionId);
}else {
resp.getWriter().write("Session已经创建,ID为:" + sessionId);
}
}
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset:utf-8");
//获取session
HttpSession session = req.getSession();
//获取属性
Person person = (Person)session.getAttribute("person");
System.out.println(person);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Cookie与Session的区别:
1、Cookie 保存在客户端浏览器中,且可以保存多个,而Session保存在服务器中;
2、生命周期:Session:在客户端浏览器第一次请求服务器时创建,当关闭浏览器,Session就销毁了;
Cookie:可以预先设定它的生存周期,可永久保存
3、Cookie不包含销毁的方法,但是可以通过设置Cookie的有效时间使其失效;
Session中包含session-destory()方法,使其失效;
4、Cookie有大小和浏览器中现存的Cookie的个数限制,Session没有大小的限制,其大小和服务器的内存大小有关;
5、Cookie本身存在安全隐患,Session较为安全;但可以通过加密和解密,增加Cookie的安全性;
6、Session创建后会在浏览器上保存一段时间,当客户端浏览器访问比较多时,会增加服务器的压力,因此在考虑到性能方面,使用Cookie比较好;
7、Cookie支持域名访问,而Session是不支持的。
推荐阅读
-
nuxt框架中路由鉴权之Koa和Session的用法
-
浅谈keras中的目标函数和优化函数MSE用法
-
PHP session有效时间和回收机制
-
大家写login.php一般用cookie还是用session?该如何解决
-
php同时使用session和cookie来保存用户登录信息的实现代码,sessioncookie_PHP教程
-
浅谈PHP eval()函数定义和用法,浅谈eval
-
cookie与session的用户登录案例(4-20)-2018年5月1日零点30分
-
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
-
从零学python系列之浅谈pickle模块封装和拆封数据对象的方法
-
详解PHP中cookie和session的区别及cookie和session用法小结,cookiesession