Cookie(中文意思为 “曲奇饼,小甜饼”): 我们这里指一种小型文本文件,通常由网站服务器发送到用户的浏览器,然后存储在用户的计算机上。用于跟踪、识别和存储关于用户在网站上的活动和偏好的信息。
Cookie 就是浏览器给页面提供的一种能持久化存储数据的机制。
服务器将 Cookie 返回给浏览器, 客户端(浏览器)这边就会通过 Cookie 保存当前用户的状态,当客户端访问服务器时,就会自动把 Cookie 内容带入到请求中,服务器接收到之后,就能知道当前客户是谁,现在客户端处于什么状态了,当前客户的服务提供到哪个环节了。Cookie 就像是 服务器在客户端搞的一个寄存处一样。
比如: 我们访问 抖音:
Key(名称)
Value (值) : 根据 Key 可以获取对应的 value.
Domain(域名): 指定可以访问 Cookie 的域名。通常情况下,Cookie 只能被设置在创建它的域名以及其子域名下。上图中我们访问的是 抖音, 那么 Cookie 的 Domain 就是 douyin.com。
Path(路径): 指定可以访问 Cookie 的路径。这个字段定义了在哪些路径下的请求可以发送 Cookie。上图中 Path 为 “/”, 说明只要是 douyin.com 这个域名, 不管访问的是抖音 的哪个路径下的资源, 都可以在请求中使用浏览器中存储的 Cookie。
Expires(过期时间): 一旦过了这个时间,浏览器将不再发送该 Cookie。如果未设置 Expires 字段,Cookie 将被视为会话 Cookie,它会在用户关闭浏览器时自动删除。
大小: 指定了 Cookie 的大小,单位为字节。
HttpOnly: 布尔值字段,设置为 true,那么该 Cookie 只能通过 HTTP 或 HTTPS 协议访问,不能通过 JavaScript 或其他客户端脚本访问。有助于增强安全性,以防止恶意脚本访问敏感信息。
Secure: 布尔值字段,设置为 true,那么该 Cookie 只能在通过 HTTPS 等安全连接发送时才会被浏览器发送到服务器。有助于保护敏感信息的传输安全。
SameSite: 限制第三方cookie,表示Cookie不随着跨域请求发送,减少安全风险。它可以有三个可能的值:Strict、Lax、None。
Strict 表示只有在同一站点的请求中才会发送 Cookie;
Lax 在某些情况下允许 Cookie 在跨站点请求中发送(例如从外部链接打开的页面);
None 允许 Cookie 在任何情况下都发送。
SameSite 设置有助于减少跨站点请求伪造(CSRF)攻击和提高隐私。
Partition Key(分区键): 一个标识符,指示 Cookie 属于哪个上下文或分区。它通常用于在浏览器中隔离不同网站或应用程序的 Cookie 数据,以增强隐私和安全性。每个不同的域名下都可以有不同的 Cookie, 不同网站之间的 Cookie 并不冲突.
Priority(优先级): 指定了 Cookie 的传输优先级。Cookie数量超出限制时低优先级会被优先清除.
响应中: 服务器通过 Set-Cookie 字段返回 Cookie 给浏览器
此时 Cookie 中包含各个字段, 如 Domain, Path, HttpOnly 等, 这是服务器让浏览器知道什么时候才能使用这些 Cookie.
浏览器接收到 Cookie 后存储下来
再次发送请求时使用 Cookie 字段, 将 Cookie 发送给 服务器。
单看请求中的 Cookie 就是:
以键值对的形式, 只有 key 和 value, 没有其他字段, 其他字段只是辅助浏览器判断什么时候在请求中使用 Cookie 的.
服务器接收到包含 Cookie 的请求后,会解析 Cookie 并根据其中的信息执行相应的操作,例如,验证用户身份、提供个性化内容或记录用户活动等。
注意: 上面这些设置都是服务器设置的, 因为 Cookie 本身就是 服务器返回给浏览器, 浏览器只是简单的进行了存储.
构造方法:
public Cookie(String name, String value) | name 表示 Cookie 的名称, value 就是对应的值 |
---|
普通方法:
方法名 | 说明 |
---|---|
String getName() | 该方法返回 cookie 的名称 |
String getValue() | 获取 cookie 的值 |
void setValue(String newValue) | 设置 cookie 的值 |
void setHttpOnly(boolean isHttpOnly) | 设置 HttpOnly 的值 |
void setSecure(boolean flag) | 设置 Secure 的值 |
void setDomain(String domain) | 设置可以访问 Cookie 的域名 |
… | … |
Cookie 有一系列对应的 get 和 set 方法.
通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对.
// 创建一个名为 "username" 的Cookie,并设置它的值为 "zhangsan"
Cookie cookie = new Cookie("username", "zhangsan");
// 设置Cookie的过期时间为1小时(以秒为单位)
cookie.setMaxAge(3600); // 3600秒 = 1小时
// 设置Cookie的路径,表示只有在指定路径下的请求才会发送该Cookie
cookie.setPath("/example");
// 设置Cookie的域名,表示只有在指定域名下的请求才会发送该Cookie
cookie.setDomain(".example.com");
// 设置Cookie为安全Cookie,只能在HTTPS连接下传输
cookie.setSecure(true);
// 设置HttpOnly属性,防止通过JavaScript访问Cookie
cookie.setHttpOnly(true);
// 将Cookie添加到HTTP响应中,以便将其发送到客户端
response.addCookie(cookie); // response 是 HttpServletResponse 的实例
通过 HttpServletRequest.getCookies() 获取到请求中的一系列 Cookie 键值对.
Cookie[] cookies = request.getCookies(); // request 是 HttpServletRequest 实例
Cookie 最重要的应用场景就是存储 会话 ID(SessionId), 进一步访问服务器后续页面时,能带上这个 id 从而让服务器知道当前用户信息。
HTTP 协议自身是属于 “无状态” 协议.
“无状态” 的含义指的是:
但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了。
上面的令牌通常就是服务器以 Cookie 形式返回给浏览器, 服务器存储的用户信息对应的就是 Session。通常情况下,一个用户关联一个 Session (会话)。
举个栗子: 这个过程和去医院看病很相似.
就诊卡就是 Cookie, 但是 Cookie 存储的数据是有限的,且易丢失,关键信息都存储在服务器上,以 会话(Session)的形式。
服务器这边就需要记录令牌信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作.
服务器同一时刻收到的请求是很多的. 服务器需要清除的区分清楚每个请求是从属于哪个用户, 就需要在服务器这边记录每个用户令牌以及用户的信息的对应关系.
在上面的例子中, 就诊卡就是一张 “令牌”. 要想让这个令牌能够生效, 就需要医院这边通过系统记录每个就诊卡和患者信息之间的关联关系.
会话的本质就是一个 “哈希表”, 存储了一些键值对结构. key 就是令牌的 ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计).
sessionId 是由服务器生成的一个 “唯一性字符串”, 又叫 token
Servlet 的 Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失,用户注销 Session 也会丢失, 同时 Session 也有过期时间。(Session 的默认过期时间30分钟)
HttpSession 这个对象本质也是一个 “键值对” 结构,每个 HttpSession 有其唯一的 ID,同时又包含若干键值对,里面的 key 和 value 由程序员自己定义,允许程序员往 HttpSession 对象中存储任意的键值对数据,但是 key 必须是 String , value 可以任意。
HttpSession 的每个键值对又称为属性(Attribute).
HttpServletRequest 类 中有 获取 Session 的方法
方法 | 描述 |
---|---|
HttpSession getSession() | 在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null |
为什么根据 HttpServletRequest 类能获取到 Session ?
图中的 ZTZiMGRkY2YtYjQzYi00MWM3LTlhZjUtNTNkZmVkN2Q0MzM0 便是 sessionId
浏览器收到 Cookie 后, 进行存储,再次发送请求时便携带着这个 sessionId, 从而服务器能识别出来用户信息。
方法 | 描述 |
---|---|
Object getAttribute(String name) | 根据 name 获取 值,找不到返回 null. |
void setAttribute(String name, Object value) | 添加键值对, 键为 name , 值为 value |
boolean isNew() | 判定当前是否是新创建出的会话 |
创建会话并存入键值对:
// request 是 HttpServletRequest 实例
HttpSession session = request.getSession(true); // 参数为 true, 没有 session 就创建
// 存入键值对
session.setAttribute("username", "zhangsan");
session.setAttribute("age", 18);
session.setAttribute("password", "123456");
根据会话获取键值对:
// request 是 HttpServletRequest 实例
HttpSession session = request.getSession(false); // 参数为 false, 没有 session 返回 null, 通常用来验证用户是否已经登录时用
// 获取键值对, 注意要转换类型, 因为 返回值类型是 Object
String username = (String) session.getAttribute("username");
int age = (int) session.getAttribute("username");
String password = (String)session.getAttribute("password");
联系:在网站的登录功能种,Cookie 与 Session 需要配合使用
区别:
好啦! 以上就是对 Cookie 和 Session 的讲解,希望能帮到你 !
评论区欢迎指正 !