【HTTP】三、HTTP状态保持机制(Cookie和Session)
前面我们提到HTTP协议的特点:无连接、无状态。无连接带来的时间开销随着HTTP/1.1引入了持久连接的机制得到了解决。现在来关注其“无状态”的特点。
所谓的无状态,就是指服务器不记录用户的信息,对于事务处理没有记忆能力,无法根据之前的状态进行本次的请求处理。这样做虽然简化了服务器的设计,但是实际工作中,一些万维网网点却很希望可以识别用户,记录用户的一些行为,比如购物网站,用户在选号一件物品后,还要继续选购其他物品,此时服务器希望记住用户的身份。再比如对于一个用户登录的页面,无状态意味着每次跳转新页面不是要再次登录, 就是要在每次请求报文中附加参数来管理登录状态,因此势必会带来一些问题。
Cookie和Session就是在客户端和服务器之间保持状态的解决方案,它弥补了HTTP无状态的缺陷。
为了理解Cookie和Session,先来举一个例子(来源于网络,特此说明):
一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
- 该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
- 发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
- 发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
这个例子可以说是非常形象了,几乎可以瞬间理解Cookie和Session的区别,首先,HTTP协议为了简单灵活,本身就是无状态的,因此并不想将其设置为有状态,否定了方法一。因此,要想维护状态就只有方法二和方法三,也就是说:客户端保持状态和在服务器端保持状态两种,这正好对应了Cookie和Session这两种解决方案。同时,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上并不是只有这一种方式。
1、Cookie机制
首先,Cookie是在客户端保持状态的方法。当某个客户端首次请求服务端时,服务端会生成一些状态信息,然后再给客户端的响应报文中添加一个首部字段:“Set-cookie”,名字是“Set-cookie”,值为Cookie的内容,因此这些状态信息就随着响应报文回到客户端,当客户端收到这样的响应时,就在它管理的Cookie文件中添加一行,将这一个Cookie值记录下来。随后,当这个客户端下一次浏览这个网站时,每发送一个HTTP请求报文,就在Cookie文件中取出对应的那一行内容,放到首部行中,一起发送给服务端,进而服务端就知道了该客户端之前的一些状态信息。

具体的,cookie的内容主要包括:名字,值,过期时间,路径和域。 路径与域一起构成了cookie的范围。如果未设置到期时间,则表示此cookie的生命周期是在浏览器会话期间,浏览器窗口关闭,并且cookie消失。生命周期为浏览器会话的cookie称为会话cookie。会话cookie通常不存储在硬盘上,而是存储在内存中。存储在硬盘上的Cookie可以在不同的浏览器进程之间共享。
当然,这个Cookie实际上是记录了用户在万维网上的一些行为,这属于个人隐私,为了让用户有拒绝接受Cookie的自由,在浏览器中可以进行相应的设置来关闭Cookie。
2、Session机制
对于Session会话机制,其实有了前面的例子也不难理解了,它是一种服务器端维护状态的机制,使用类似哈希表这样的结构来保存信息。
当程序需要为客户端的请求创建会话时,服务器首先检查客户端的请求是否包含会话标识符(称为会话ID)。如果包含它,它先前已为此客户端创建了一个会话。服务器根据会话ID检索会话(无法检索,将创建新会话),如果客户端请求不包含会话ID,则为客户端创建会话并生成与会话关联的会话ID。 session id应该是一个既不重复也不容易被复制的字符串。会话ID将返回给客户端以保存此响应。

那么这个Session Id如何返回到客户端呢,这可以使用cookie的方式,将其放到首部行中返回给客户端进行保存,如果禁用了Cookie,可以适应URL重写的方法,将ID附加到URL中返回去。
3、Cookie和Session的对比
那么总结起来,我们看看Cookie和Session的区别究竟在哪里。
- 不同的存储位置。Cookie将状态信息保持在客户端,Session保存在服务端,这是最大的区别。
- 不同的数据类型。只有ASCII字符串可以存储在cookie中,而Session采用哈希表的方式,可以保存任意类型的数据。
- 不同的隐私政策和安全性。Cookie存储在客户端阅读器中,对客户端可见,因此可能会产生伪装等安全问题,所以尽量不要用Cookie来保存敏感信息,或者采取加密的方法,而Session会话存储在服务器上,对客户端是透明的。不存在敏感信息泄露的风险。
- 有效期的差异。将Cookie的过期时间设为一个很大的值就可以实现永久记录信息,而Session Id可能会依赖Cookie,如果到时时间太短,Session会很快失效,而过期时间太长,会使得服务器端累积大量的Session,导致内存溢出。
- 不同的服务器压力。Session保留在服务器端,每个用户都将生成一个会话。如果有很多并发用户,它会产生大量的Session并消耗大量内存。因此,具有高并发流量的站点不太可能使用Session来跟踪客户会话。而Cookie保留在客户端上,不消耗服务器资源。如果有很多用户同时阅读,那么cookie是一个不错的选择,比如Google、Baidu、Sina,cookies可能是唯一的选择。
- 单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的cookie不能超过3K。
参考链接:
https://www.cnblogs.com/lonelydreamer/p/6169469.html
https://baijiahao.baidu.com/s?id=1612804856429135825&wfr=spider&for=pc
【HTTP】三、HTTP状态保持机制(Cookie和Session)的更多相关文章
- Django基础(三)_分页器、COOKIE与SESSION、FORM表单
分页器(paginator) 分页器的使用 >>> from django.core.paginator import Paginator >>> objects ...
- http无状态协议,cookie和session详解(一)
1.HTTP无状态协议 首先看百度百科给出的定义: HTTP无状态协议,是指协议对于事务处理没有记忆能力.缺少状态意味着如果后续处理需要前面的信息,则它必须重传, 这样导致可能每次连接传送的数据量增大 ...
- Django之会话机制cookie、session使用
login视图函数: def login(request): if request.method == 'POST': username = request.POST.get('username') ...
- Django边学边记--状态保持(cookie和session)
Cookie 概念: Cookie,也叫Cookies,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密),好比会员卡或餐票. 特点: Cookie是由服务 ...
- cookie 和 session 机制
cookie机制 Cookie实际上是Web服务端与客户端(典型的是浏览器)交互时彼此传递的一部分内容,内容可以是任意的,但要在允许的长度范围之内.客户端会将它保存在本地机器上(如IE便会保存在本地的 ...
- Hibernate 对象的三种状态
hibernate对象的三种状态: (一) 瞬时(临时)状态: 对象被创建时的状态,数据库里面没有与之对应的记录! (二) 持久状态: 处于session的管理中,并且数据库里面存在与之对应的 ...
- hibernate对象的三种状态及转换
一.hibernate对象三种状态 Transient(瞬时状态):没有session管理,同时数据库没有对应记录 举例:new 出来的对象还没有被session管理,此时该对象处于Transient ...
- 【SSH】——Hibernate三种状态之间的转化
Hibernate的三种状态为:transient.persistent和detached.对这三种状态的理解可以结合Session缓存,在Session缓存中的状态为persistent,另外两种不 ...
- 傻傻分不清之 Cookie、Session、Token、JWT
傻傻分不清之 Cookie.Session.Token.JWT 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打 ...
- 还分不清 Cookie、Session、Token、JWT?一篇文章讲清楚
还分不清 Cookie.Session.Token.JWT?一篇文章讲清楚 转载来源 公众号:前端加加 作者:秋天不落叶 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证 ...
随机推荐
- jar启动名称示例
nohup java -jar -Dspring.profiles.active=20dev -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+Print ...
- jquery easyui 日历控件和文本框结合使用生成日期
html部分---等待接收所选日期的文本框 <td> <input name='input_date' required class='easyui-textbox' id='xiw ...
- 【转载】浅析python日志重复输出问题
出处:https://www.cnblogs.com/huang-yc/p/9209096.html 问题起源: 在学习了python的函数式编程后,又接触到了logging这样一个强大的日志模块 ...
- .NET-list扩展方法Distinct去重
原文链接:https://blog.csdn.net/daigualu/article/details/70800012 .NET中list的扩展方法Distinct可以去掉重复的元素,分别总结默认去 ...
- 京东POP店铺使用京东物流切仓操作方法
首先进入京东物流工作台:https://wl.jdwl.com/ 在运营管理中,点击店铺商品 然后看截图操作
- 20.包含min函数的栈(python)
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). # -*- coding:utf-8 -*- class Solution: def ...
- C# socket 与网页通讯
class Program { static Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, Pr ...
- TTTTTTTTTTTTT 树的直径 Codeforces Beta Round #14 (Div. 2) D. Two Paths
tiyi:给你n个节点和n-1条边(无环),求在这个图中找到 两条路径,两路径不相交,求能找的两条路径的长度的乘积最大值: #include <iostream> #include < ...
- Android的SQLite基本操作
涉及SQLite的增删改查,结果用log显示 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...
- linux查看端口占用情况,python探测端口使用的小程序
Linux如何查看端口 1.lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000 # lsof -i:8000 COMMAND PID USER ...