本文共 4320 字,大约阅读时间需要 14 分钟。
概念 |
在了解Cookie之前,首先知道我们在做web开发的时候使用的Http协议是一种无状态协议
,也就是说浏览器向Web服务器发送的每一个请求都是完全独立没有联系的。连续发送两次请求,对于Web服务器端来说不知道两次请求是否来自于同一个用户。
针对于无状态协议
的特性,往往我们在编程的时候又是需要Web服务器清楚了解自己接收的请求是来自于哪个浏览器。
添加商品到购物车
的请求最终会放到我的购物车中。 前文所说的这种机制就是会话与状态管理
。
会话状态
将属于同一会话的一系列请求和响应联系起来。 web服务器要想能够识别每次接收到的请求到底是哪个浏览器发送的,那么客户端就需要对发送的请求进行标识,如果是同一个会话,那么请求中附带的标识一样,不同会话的请求信息它的标识号不同。而这个标识号就是SessionID。
常用的会话跟踪方案有以下两种:
1.Cookie(客户端会话技术:将数据存到客户端) 2.Session(服务器端会话技术:将数据存到服务器端)Cookie |
下图解释了Cookie在web浏览器与web服务器之间进行交互的时候传输过程:
1. 当浏览器向web服务器端发起某个请求,第一次访问服务器端的时候,请求中是不带Cookie的,当请求到达服务器端,服务器会在响应头中附带传送给浏览器端一个小文本文件。2. 浏览器接收到web服务器端响应的数据并解析Cookie,将Cookie保存为文件,以后每次该浏览器向web服务器发送请求的时候,都会在请求体消息中带上此Cookie信息。
3. web服务器端接收到来自浏览器的请求,并对Cookie进行解析,获取Cookie信息。
还是用撸代码表示一下:
首先创建两个项目(使用IDEA创建项目的时候勾选上Spring Web依赖)
项目一:端口8083
@Controller@RequestMapping("/index")public class CookieDemo1 { @RequestMapping("/addCookie") public void addCookie(HttpServletResponse response){ //1.创建Cookie Cookie cookie = new Cookie("name", "良民"); //2.发送Cookie response.addCookie(cookie); }}
项目二:端口8084
@Controller@RequestMapping("/index")public class getCookie { @RequestMapping("/getCookie") public void getCookie(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { System.out.println("Cookie的名称:" + cookie.getName() +"|||||"+ "Cookie的值:" + cookie.getValue()); } } }}
1.现在先访问一下8084端口项目:
发现request中没有Cookie信息。2.再访问一下8083端口:
发现Cookie被写到response响应信息中3.再次访问8084端口:
从request中发现了Cookie信息。 从这里也印证了前面Cookie传输过程图
。
1. 如果没有设置Cookie的过期时间,则默认是浏览器关闭的时候,Cookie消失。此种Cookie的生命周期就是浏览器会话期间,也叫会话Cookie,会话Cookie一般存在内存上而不是硬盘上。
2. 如果设置了Cookie存活时间,则浏览器会将此Cookie存放到硬盘上,关闭浏览器之后再打开浏览器,如果此Cookie没有被手动清除并且没有到过期时间,则此Cookie依然有效。
设置Cookie存活时间:
cookie.setMaxAge(存活多少秒)
当cookie.setMaxAge()
设置为0时,会在浏览器上马上删除指定的cookie。
cookie.setMaxAge()
设置为-1时,代表关闭当前浏览器Cookie即失效。 注意:Cookie是存放在客户端上的
假如在一个Tomcat服务器中部署了多个web项目,那么在默认的情况下,这些web项目中的Cookie信息是不能够共享的。
cookie.setPath()
方法可以指定cookie的取值范围,也就是说调用了该方法指定了路径之后,那么该路径下的所有资源均可共享Cookie信息。
cookie.setPath("/")
)。 不同的Tomcat服务器之间的项目是可以共享的,借助cookie.setDomain(String pattern)
方法既可以实现。前提是不同的项目的一级域名相同
此方法的参数应该是两个项目之间共同的域名 ,比如:news.baidu.com
和map.baidu.com
两个项目之间,实现cookie共享参数为.baidu.com
;
1. Cookie存储于客户端,也正因为存储于客户端,所以Cookie安全系数相对于存储在服务器端的Session来说较低,容易被人篡改。
2. Cookie数据有大小限制,单个Cookie最大限制为4kb。同一个域名下的Cookie数量上限为20个(浏览器存储的Cookie信息可以在浏览器的设置中查看)。
1. Cookie一般用于存储少量不太敏感的数据。
2. 在不登录的情况下,完成服务端对客户端的身份识别。
Cookie案例 |
需求:
访问一个接口,如果是第一次访问,则返回:“您好!欢迎您首次访问!”
,如果不是第一次访问,则返回欢迎回来:”2019年10月23日-11:03:43
(时间为上次访问的时间)
@Controller@RequestMapping("/cookieIndex")public class CookieTest { @RequestMapping("/queryCookie") public void queryCookie(HttpServletRequest request, HttpServletResponse response) throws IOException { //1.因为需求中需要response的数据中有中文,所以设置字符集 response.setContentType("text/html;charset=utf-8"); //2.获取所有cookies Cookie[] cookies = request.getCookies(); //获取当前时间 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年mm月dd日-HH:mm:ss"); String date = sdf.format(new Date()); if (cookies != null && cookies.length > 0) { for (Cookie cookie : cookies) { String name = cookie.getName(); if ("lastTime".equals(name)) { //3.1如果cookie中有lastTime的数据 //3.2获取该cookie对应的value值(也就是上次访问的时间) String value = cookie.getValue(); //3.3将value值打印出来 response.getWriter().write("欢迎回来:" + value); //3.4向cookie中放入新的访问时间 cookie.setValue(date); //设置存活时间1小时 cookie.setMaxAge(60*60); response.addCookie(cookie); //3.5停止for循环 break; } } } else { //没有cookie信息 //4.打印首次访问信息 response.getWriter().write("欢迎您首次访问"); //5.new 一个新的cookie,放到响应中 Cookie cookie = new Cookie("lastTime", date); cookie.setMaxAge(60); response.addCookie(cookie); } }}
访问地址:http://localhost:8084/cookieIndex/queryCookie
(此项目的端口号我设置为8084)
转载地址:http://dnhwi.baihongyu.com/