一、Cookie原理分析
Cookie的实现原理是基于HTTP协议的,其中涉及到HTTP协议中请求头和响应头信息:
响应头:set-cookie
请求头: cookie
客户端浏览器访问服务器时,服务器通过在 HTTP 响应中增加 Set-Cookie 响应头字段
,将数据信息发送给浏览器。
浏览器获取到响应结果后,从响应头中就可以获取到Set-Cookie
对应值,并将 Cookie 保存在浏览器内存中或硬盘上。
再次请求该服务器时,浏览器通过在 HTTP 请求消息中增加 Cookie 请求头字段
,将 Cookie 回传给 Web 服务器。
服务器根据 Cookie 信息跟踪客户端的状态,Request对象会把请求头中cookie对应的值封装成一个个Cookie对象,最终形成一个cookie数组
向浏览器发送cookie
从浏览器缓存中获取cookie
二、Cookie使用细节
1️⃣Cookie的存活时间
默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁,即会话级Cookie
设置Cookie存储时间
设置Cookie存活时间,即持久级Cookie, 此时Cookie存到了电脑磁盘
上
// 单位:秒setMaxAge(int seconds)
seconds的参数设置详情
正数
:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
负数
:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁
零
:使用 setMaxAge(0) 手动删除 Cookie时,需要使用 setPath 方法指定 Cookie 的路径,且该路径必须与创建 Cookie 时的路径保持一致
2️⃣Cookie存储中文
默认Cookie不能存储中文,直接传入中文会报500的错误
解决方案
在AServlet中对中文进行URL编码,采用URLEncoder.encode()
,将编码后的值存入Cookie中
在BServlet中获取Cookie中的值,获取的值为URL编码后的值
将获取的值在进行URL解码,采用URLDecoder.decode()
,就可以获取到对应的中文值
示例
在Servlet1中对中文进行URL编码
@WebServlet("/c1")public class CookieDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.对中文进行UTF-8编码 String username = "倔强的牛角"; String encodeUserName = URLEncoder.encode(username, StandardCharsets.UTF_8); // 2.创建cookie对象,存入编码后的中文 Cookie c1 = new Cookie("username", encodeUserName); Cookie c2 = new Cookie("password", "123456"); // 3.设置存活时间,1周 7天 c1.setMaxAge(60*60*24*7); c2.setMaxAge(60*60*24*7); // 4.向浏览器发送cookie response.addCookie(c1); response.addCookie(c2); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); }}
在Servlet2中获取值,并对值进行解码
@WebServlet(name = "CookieDemo", value = "/c2")public class CookieDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.获取cookie数组 Cookie[] cookies = request.getCookies(); // 2.遍历数组 for (Cookie cookie : cookies) { String cookieName = cookie.getName(); String cookieValue = cookie.getValue(); if ("username".equals(cookieName)) { // 对中文进行UTF-8解码 String decodeUserName = URLDecoder.decode(cookieValue, StandardCharsets.UTF_8); System.out.println("key:" + cookieName + ",value:" + decodeUserName); continue; } System.out.println("key:" + cookieName + ",value:" + cookieValue); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); }}
演示结果
存储到浏览器的是编码后的中文
获取编码的中文,并解码
三、Cookie的缺点
Cookie 虽然可以解决服务器跟踪用户状态的问题,但是它具有以下缺点:
在 HTTP 请求中,Cookie 是明文传递的,容易泄露用户信息,安全性不高。
浏览器可以禁用 Cookie,一旦被禁用,Cookie 将无法正常工作。
Cookie 对象中只能设置文本信息(字符串)信息。
客户端浏览器保存 Cookie 的数量和长度是有限制的。
原文:https://juejin.cn/post/7102440383598526477