「Java Web 系列」Cookie 的原理分析和使用细节

一、Cookie 原理分析

Cookie 的实现原理是基于 HTTP 协议的,其中涉及到 HTTP 协议中请求头和响应头信息:

  • 响应头:set-cookie

  • 请求头: cookie

  1. 客户端浏览器访问服务器时,服务器通过在 HTTP 响应中增加 Set-Cookie 响应头字段,将数据信息发送给浏览器。

  2. 浏览器获取到响应结果后,从响应头中就可以获取到Set-Cookie对应值,并将 Cookie 保存在浏览器内存中或硬盘上。

  3. 再次请求该服务器时,浏览器通过在 HTTP 请求消息中增加 Cookie 请求头字段,将 Cookie 回传给 Web 服务器。

  4. 服务器根据 Cookie 信息跟踪客户端的状态,Request 对象会把请求头中 cookie 对应的值封装成一个个 Cookie 对象,最终形成一个 cookie 数组

  • 向浏览器发送 cookie

  • 从浏览器缓存中获取 cookie

二、Cookie 使用细节

1️⃣Cookie 的存活时间

默认情况下,Cookie 存储在浏览器内存中,当浏览器关闭,内存释放,则 Cookie 被销毁,即会话级 Cookie

设置 Cookie 存储时间

  • 设置 Cookie 存活时间,即持久级 Cookie, 此时 Cookie 存到了电脑磁盘

// 单位:秒setMaxAge(int seconds)

复制代码

  • seconds 的参数设置详情

  1. 正数:将 Cookie 写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除

  2. 负数:默认值,Cookie 在当前浏览器内存中,当浏览器关闭,则 Cookie 被销毁

  3. :使用 setMaxAge(0) 手动删除 Cookie 时,需要使用 setPath 方法指定 Cookie 的路径,且该路径必须与创建 Cookie 时的路径保持一致

2️⃣Cookie 存储中文

默认 Cookie 不能存储中文,直接传入中文会报 500 的错误

解决方案

  1. 在 AServlet 中对中文进行 URL 编码,采用URLEncoder.encode(),将编码后的值存入 Cookie 中

  2. 在 BServlet 中获取 Cookie 中的值,获取的值为 URL 编码后的值

  3. 将获取的值在进行 URL 解码,采用URLDecoder.decode(),就可以获取到对应的中文值

示例

  1. 在 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);    }}

复制代码

  1. 在 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);    }}

复制代码

  1. 演示结果

  • 存储到浏览器的是编码后的中文

  • 获取编码的中文,并解码

三、Cookie 的缺点

Cookie 虽然可以解决服务器跟踪用户状态的问题,但是它具有以下缺点:

  • 在 HTTP 请求中,Cookie 是明文传递的,容易泄露用户信息,安全性不高

  • 浏览器可以禁用 Cookie,一旦被禁用,Cookie 将无法正常工作。

  • Cookie 对象中只能设置文本信息(字符串)信息。

  • 客户端浏览器保存 Cookie 的数量和长度是有限制的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值