Cookie和Session学习笔记

Cookie

HTTP协议本身是无状态的。每次信息交流完毕后,服务端和客户端便失去了联系,等下一次访问时,并不知道客户端之前有没有访问。相当于每次都是一次新的访问请求,当应用到登录功能时,每当用户请求一个新的页面,就要重新验证一次用户的身份,这样显得特别麻烦。因此,为了解决这一问题,Cookie应运而生。
Cookie实际上是一小段的文本信息(key-value格式)。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。
举例:去商家购物,商家(服务端)给你(客户端)一张可以盖章的礼品卡(Cookie),每次购物完成后可以把礼品卡拿给商家盖章。这张礼品卡就可以记录你和商家之间交易的信息。

具体使用

发送cookie

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=utf-8");
		
		Cookie cookie = new Cookie("name", "abc");
		cookie.setMaxAge(20);
		resp.addCookie(cookie);
		
		resp.getWriter().write("cookie已发送");
	}

当访问结束后,在浏览器端可以看到发送过来的cookie
在这里插入图片描述

接收cookie

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Cookie[] cookies = req.getCookies();
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				System.out.println(cookie.getName()+"---"+cookie.getValue()+"---"+cookie.getPath());
			}
		}
		else {
			System.out.println("没有cookie");
		}
	}

请求完成后,将在控制台打印出cookie的相关信息
在这里插入图片描述
如果直接获取cookie(没有发送过cookie)
在这里插入图片描述

cookie的相关属性

name:一个cookie的名称
value:一个cookie的值
domain:可以访问此cookie的域名
path:可以访问此cookie的页面路径
Size:此cookie大小
http:cookie的httponly属性,若此属性为True,则只有在http请求头中会有此cookie信息,而不能通过document.cookie来访问此cookie。
secure:设置是否只能通过https来传递此条cookie。
expires/Max-Age:设置cookie超时时间。如果设置的值为一个时间,则当到达该时间时此cookie失效。不设置的话默认是session,意思是cookie会和session一起失效,当浏览器关闭(并不是浏览器标签关闭,而是整个浏览器关闭)后,cookie失效。
浏览器端属性项
可以通过设置cookie的属性值来改变过期时间(单位为秒)

cookie.setMaxAge(int expiry);

(1)当expiry的值为正数时,表示expiry后过期;
(2)当expiry等于0时,表示删除cookie;
(3)当expiry为负数时,表示这是一个临时cookie,仅在本浏览器窗口或本窗口打开的子窗口有效,关闭浏览器后该cookie立即失效。

修改或删除cookie

由于HttpServletResponse对cookie的操作仅提供有addCookie(Cookie cookie),所以当想删除或者修改cookie时,可以通过设置cookie的maxAge来实现。
删除cookie:将cookie的maxAge设置为0,然后再覆盖掉之前的cookie

cookie.setMaxAge(0);
resp.addCookie(cookie);

同样,如果想要修改某cookie,则只需要新建一个同名的cookie覆盖掉之前的即可。但完成这些操作的前提是,新建的cookie,除了value、maxAge之外的属性,其他如name、path、domain等都必须与原来的一样,否则浏览器将视为不同的两个cookie,从而使操作失效。

注意: 客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name和value属性,maxAge属性只被浏览器用来判断Cookie是否过期,而不能用服务端来判断。 我们无法在服务端通过cookie.getMaxAge()来判断该cookie是否过期,maxAge只是一个只读属性,值永远为-1。当cookie过期时,浏览器在与后台交互时会自动筛选过期cookie,过期了的cookie就不会被携带了。

域名限制访问权限

ookie是不可以跨域名的,如a.bb.com和b.bb.com是不可以共享cookie的。若想要共享cookie,可以通过设置cookie的domain属性来实现,如

cookie.setDomain(".bb.com");

路径

浏览器在请求时,会把cookie带回客户端,但是如果有多个cookie,该带谁回去呢,这就需要用到路径了。举例如下:
如果现在有两个cookie,A和B,路径分别为 /demo和 /demo/exp。那么,当访问如下链接时,会出现两种情况
(1)http://localhost/demo,会发送cookie A
(1)http://localhost/demo/exp,会发送cookie A和cookie B
也就是说,当请求某个路径的cookie时,会将其父路径的cookie也发送回去;而在访问父路径时,不会带上子路径的cookie。

Session

Session是另一种记录客户状态的机制,不同的是 Cookie保存在客户端浏览器中,而Session保存在服务器上 。
举例: 去商家购物时,如果商家给你卡片,你完全可以自己盖章,不用到商家去盖章也可以,这就造成了cookie不安全的情况。数据保存在客户端,很不安全。但此时商家改变策略,不给你卡片(cookie),只给你一个卡号(session),去购物时只需要告诉店家卡号,店家便会给你记一次,这样记录保存在商家(服务端),比客户端更为安全。
从某方面讲,其实session是建立在cookie的机制之上的,如果cookie被禁,那么通过cookie的方式便不能实现session,此时需要进行URL地址重写。

具体使用

用如下例子来测试session

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
		
		HttpSession session = request.getSession();
		session.setAttribute("username", "xiaoming");
		String sid = session.getId();
		
		PrintWriter out = response.getWriter();
		
		//如果session是新的
		if (session.isNew()) 
		{
			out.print("新的session,sid="+sid);
		}
		else
		{
			out.print("旧的session,sid="+sid);
			out.print(session.getAttribute("username"));
		}
	}

第一次访问,属于最新浏览,打印出sid
在这里插入图片描述
第二次访问,可以看到sid是不变的,切打印出了session保存的一个内容
在这里插入图片描述

重写URL

当浏览器禁用cookie时,可以采用URL重写机制实现会话保持。

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
		
		HttpSession session = request.getSession();
		session.setAttribute("username", "xiaoming");
		
		String sid = session.getId();
		
		PrintWriter out = response.getWriter();
		
		//如果session是新的
		if (session.isNew()) 
		{
			String url = response.encodeURL("SendServlet");
			System.out.println("新的");
			response.sendRedirect(url);
		}
		else
		{
			out.print("旧的session,sid="+sid);
			out.print(session.getAttribute("username"));
		}
		
	}

第一次访问是新的,然后重定向到重写URL的网址
在这里插入图片描述
在这里插入图片描述
接下来不管怎么刷新,sid一直不变,说明就算禁用了cookie,也还可以通过此方法实现会话保持。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值