HTTP之Cookie和Session

1. HTTP的基本性质

1.1 优点

  • 支持客户端/服务器模式。

即客户端打开连接发出请求,然后服务器根据该请求给出响应;

  • 简单快速。

HTTP的报文格式是header+body,头部信息是key-value,文本简单,同时客户向服务器请求服务时,只需传送请求方法和路径

  • 灵活

HTTP允许传输任意类型的数据对象.

1.2 缺点

  • HTTP是无状态的。

在同一个连接中,两次执行成功的请求之间没有任何关系
优点:因为服务器不会去记录HTTP的状态,所以不需要额外的资源来记录状态信息,减轻了服务器的负担;
缺点:因为没有记忆能力,如果后续操作需要前面的信息,必须重传,效率低。例如,用户在进行购物时,用户将某一个商品加入购物车,切换页面后,再次添加另一个商品,者两次添加商品的请求之间没有任何关系。因此,浏览器就无法知道用户最终选择了哪些商品。可使用HTTP的头部进行扩展来解决此问题。

2. HTTP无状态的解决方案

2.1 Cookie(小甜饼)

  • 定义
  1. 是服务器发送到浏览器,并保存到浏览器的一小块数据
  2. 浏览器下次访问该服务器时,会自动携带该块数据,将其发送给服务器。
  3. 主要用于服务器判断请求是否来自同一个浏览器
  • 原理
  1. 通过在请求和响应报文中写入Cookie信息来控制客户端的状态。当客户端第一次向服务器请求信息时,会在服务器端生成一个客户端特有的识别码,以此为索引放在服务器的后端数据库中,并在响应报文中添加cookie返回,客户端会保存Cookie信息;
  2. 当该客户端再次向服务器发送请求报文时,会在请求报文中添加Cookie信息,服务器在收到请求报文时,检查后端数据库中是否在存在Cookie,提高了回复相应报文的速度。
  • 在项目中的实际应用

问题1:客户端如何得到Cookie?答: 服务器端给出响应。
问题2:服务器端如何验证Cookie?答:客户端发送请求。
程序编写思路:

  1. 服务器端生成cookie,然后放在响应报文的头部,返回给浏览器
    1.1 生成Cookie,每个cookie是一个key-value对象;
    1.2 设置Cookie的生效路径(即访问路径为哪些时,才会带上Cookie);
    1.3 设置Cookie的生存时间(即关闭浏览器Cookie可能就删除了).
  2. 浏览在下次请求的时候会带上cookie。
  • 程序代码测试
/*
* 服务器生成Cookie
* */
@RequestMapping(path = "/cookie/set", method = RequestMethod.GET)
@ResponseBody
public String setCookie(HttpServletResponse response) {
    Cookie cookie = new Cookie("code", CommunityUtil.generateUUID());
    cookie.setMaxAge(60 * 10);
    cookie.setPath("/community/alpha");
    response.addCookie(cookie);

    return "set cookie";
}

/*
 * 浏览器发送Cookie
 * */
@RequestMapping(path = "/cookie/get", method = RequestMethod.GET)
@ResponseBody
public String getCookie(@CookieValue("code") String code) {
    System.out.println(code);

    return "get cookie";
}
  • 缺点:因为保存在客户端,不安全,引入Session机制

2.2 Session

  • 定义
  1. 用于在服务端记录客户端信息;
  2. 数据放在服务端会更加安全,但是会增加服务端的内存压力
  • 原理
  1. 服务器端生成一个Session,存储浏览器的各种信息,同时有唯一的一个sessionId,服务器通过识别这个sessionId来实现业务的连续;
  2. 同时服务器端隐式的生成一个Cookie用于存放sessionId,会放在响应报文中返回给浏览器,浏览器会保存Cookie;
  3. 下次访问服务器时会携带此Cookie用于判断.
  • 程序代码测试
/*
* 服务器端生成session
* */
@RequestMapping(path = "/session/set", method = RequestMethod.GET)
@ResponseBody
public String setSession(HttpSession session) {
    session.setAttribute("id", 1);
    session.setAttribute("name", "test");
    return "set session";
}

/*
 * 浏览器发送请求的时候session
 * */
@RequestMapping(path = "/session/get", method = RequestMethod.GET)
@ResponseBody
public String getSession(HttpSession session) {
    session.getAttribute("id");
    session.getAttribute("name");
    return "get session";
}
  • 缺点

占用服务器的内存.

2.3 扩展:实际生产环境中为何不直接采用sesson?

原因:现实生活中多采用分布式集群架构,中间利用njx保证负载均衡;若服务器A为此请求生成了session,下一次请求时,因njx可能会请求到另一台服务器上,重新生成Cookie,占用大量内存。
优化:设置分配策略

  1. 利用黏性session: 记住上次访问主机的IP地址,下一次同一请求,还来请求这台服务器;【缺点:无法保证负载均衡】
  2. 利用同步session: 每生成一个session,在服务器集群中同步该session;【缺点:1. 同步对服务器产生性能影响;2. 服务器之间产生耦合,对部署不利。】
  3. 利用共享session: 专门设置一台服务器,用于存放session;【缺点:单机存在性能瓶颈,一旦宕机,则无法使用】
  4. 利用数据库[推荐使用]:大部分存在浏览器中,敏感数据直接放在mysql数据库集群中;【缺点:数据存放在硬件中,性能低】==> 优化:利用Redis数据库存放

3. Cookie和Session的比较

3.1 两者的形象比喻

  1. Cookie机制通过检查客户身上的通行证来确定客户身份;
  2. Session机制通过检查服务器上的客户明细表确认客户身份。

3.2 两者区别

  1. Cookie数据存放在客户的浏览器上;Session数据存放在服务器上;
  2. Session相对于Cookie更加安全
  3. 如果考虑减轻服务器的负担,应当使用Cookie。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桃花猿

客官,赏点打酒钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值