1. 基本概念
1.1 HTTP 协议
HTTP 是Web 浏览器和服务器之间的通信协议。指定客户端与服务器端如何建立连接、发送请求、响应请求、关闭连接。
HTTP 连接使用TCP/IP 来传输数据,TCP 传输层,IP 网络层,而HTTP 位于应用层。
1.2 会话(无状态)
打开浏览器,通过HTTP协议,访问网络资源,然后关闭浏览器,这个过程就是一个会话。
但HTTP 本身属于无状态协议,每次访问都是独立的,服务器端不会记录客户端操作,也被称为无状态会话。
1.3 有状态会话
利用Cookie 可以跟踪每个用户和会话,服务器端记录客户端操作,从而可以保存会话状态,这样的会话称为有状态会话。
这个会话状态是保留在客户端上的,当Cookie 被清除,或者失效,这个会话状态就没有了。
2. 常见疑问
2.1 Cookie 只有在JavaWeb 中吗?
不只是在JavaWeb 中存在,只要是Web 开发,只要是B/S 架构的系统,只要是基于Http 协议,就有Cookie 的存在。
2.2 Cookie 有什么实际应用?
保留购物车商品的状态在客户端(N天免登陆)
2.3 Cookie 存在哪?
Cookie 可以保存在浏览器缓存中,浏览器关闭Cookie消失;
Cookie 也可以保存在客户端的硬盘文件中,浏览器关闭Cookie 还在,除非Cookie 失效。
补充:存放在硬盘当中的位置:Internate选项-设置(删除旁边)-查看文件。
2.4 Cookie 可以禁用吗?
浏览器可以禁用Cookie,禁用后服务端发送过来的Cookie,浏览器不再接收。
3. Java 中的Cookie
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取浏览器请求中的 Cookie
Cookie[] cookies = req.getCookies();
if(cookies != null){
for (int i = 0; i < cookies.length;i++) {
System.out.println("not first time");
Cookie cookie = cookies[i];
// 获取Cookie 中的值
System.out.println(cookie.getName());
System.out.println(cookie.getValue());
}
}
// 创建Cookie
Cookie cookie = new Cookie("name","chengyu");
// 添加Cookie
resp.addCookie(cookie);
}
}
4. Cookie 有效期
4.1 默认情况
默认情况下,服务器发送Cookie 给浏览器之后,浏览器将Cookie 保存在缓存当中,只要不关闭浏览器,Cookie 永远存在,并且有效;
当浏览器关闭之后,缓存中的Cookie 被消除;
4.2 设置有效期
Cookie 有效时长 = 0,直接被删除
Cookie 有效时长 < 0,不会存储
Cookie 有效时长 > 0,存储在硬盘文件当中
Cookie cookie = new Cookie("name","chengyu");
cookie.setMaxAge(10); // 有效时长,单位秒
resp.addCookie(cookie);
5. Cookie 作用域
5.1 客户端携带Cookie
客户端无论是硬盘中还是缓存中,将会存放不同服务器的Cookie 信息,浏览器是否提交这些Cookie 给服务器,取决于请求路径,请求路径和Cookie 是紧密关联的,不同的请求路径发送不同的Cookie,访问哪个服务器就带上哪个服务器设定的Cookie。
5.2 指定域 setDomain
默认情况下,Cookie 来自哪个服务器就应用于哪个服务器。
例如,如果一个Cookie 由 www.chengyu.example.com 设置,浏览器只把这个Cookie 发送给www.chengyu.example.com。
但也可以通过setDomain 设置Cookie 作用于整个子域,而不只是最初的服务器。
// 创建Cookie
Cookie cookie = new Cookie("name","chengyu");
// 域设置
cookie.setDomain(".chengwei.example.com");
// 添加Cookie
resp.addCookie(cookie);
这样设置之后,a.chengwei.example.com、b.chengwei.example.com、abc.chengwei.example.com 等子域都会共享 Cookie,实现跨域访问。
但服务器只能为它直接所属的域设置Cookie,.com 这种域是无法设置的。
5.3 指定路径 setPath
默认情况下,作用域是最初的URL 和所有子目录。
例如,url访问 /servlet/test/createAndSendCookie 请求服务器,服务器生成Cookie,并将Cookie 发送给浏览器客户端,这个浏览器中的Cookie 会默认和“ /servlet/test/”(全路径的上一级/)这个路径绑定在一起,也就是说,以后只要发送“ /servlet/test/”请求,Cookie 一定会提交给服务器。
但也可以通过setPath 设置Cookie 改变默认作用域,如下面的设置,Cookie 只作用于/kong 子目录,而不能应用于网站的其他部分。
// 创建Cookie 对象
Cookie cookie = new Cookie("userName","chengyu");
// 设置路径
cookie.setPath(request.getContextPath() + "/kong");
// 将Cookie 对象发送给浏览器客户端
reponse.addCookie(cookie);