Cookie
一、概述
HTTP 协议是无状态的,为了让 HTTP 协议尽可能简单,使得它能够处理大量事务。HTTP 引入 Cookie 来保存状态信息。
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。
由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销(尤其是在移动环境下)。
二、主要用途
- 会话跟踪(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 浏览器行为跟踪(如跟踪分析用户行为等)
三、创建方式
在客户端给服务器发送完HTTP请求之后,服务器可以在反馈的HTTP响应报文中包含 Set-Cookie 首部字段,客户端得到响应报文后把 Cookie 内容保存到浏览器中。
HTTP响应报文如下
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: user_id=1
Set-Cookie: user_name=kobe
Set-Cookie: role_type=1
客户端之后对同一个服务器发送请求时,会从浏览器中取出 Cookie 信息并通过 Cookie 请求首部字段发送给服务器。
再次进行HTTP请求的报文如下
GET /index.html HTTP/1.1
Host: www.test.com
Cookie: user_id=1; user_name=kobe;role_type=1
四、分类
- 会话期 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。
- 持久性 Cookie:指定过期时间(Expires)或有效期(max-age)之后就成为了持久性的 Cookie。
若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。
若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在浏览器的不同进程间共享。
如下所示,这是一个持久性的Cookie,过期时间为2019年6月10日晚6点半。
Set-Cookie: user_id=1; Expires=Mon, 10 Jun 2019 18:30:00 GMT;
五、作用域
Path属性
Path 标识指定了主机下的哪些路径可以接受 Cookie(该 URL 路径必须存在于请求 URL 中)。以字符 %x2F ("/") 作为路径分隔符,子路径也会被匹配。例如,设置 Path=/docs,则以下地址都会匹配:
- /docs
- /docs/Web/
- /docs/Web/HTTP
Domain属性
Domain 标识指定了哪些主机可以接受 Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了 Domain,则一般包含子域名。例如,如果设置 Domain=test.org,则 Cookie 也包含在子域名中(如 abcd.test.org)。
Session
一、概述
Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而Session 保存在服务器上。
客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是 Session 。客户端浏览器再次访问时只需要从该 Session中查找该客户的状态就可以了。
Session 可以存储在服务器上的文件、数据库或者内存中。也可以将 Session 存储在 Redis 这种内存型数据库中,效率会更高。
二、Session的创建与使用
拿最常见的使用Session维护用户登录状态举个例子
- 用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
- 服务器验证该用户名和密码(此时还没有创建Session),如果正确(此时创建Session,获取Session ID)则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID;
- 服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中;
- 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之前的业务操作。
三、禁用cookie
如果客户端禁用了Cookie,通常有两种方法实现Session而不依赖Cookie。
- 使用 URL 重写技术,将 Session ID 作为 URL 的参数进行传递。
- 使用表单隐藏字段。服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把 Session ID 传递回服务器。
<form name="testform" action="/xxx">
<input type="hidden" name="sessionid" value="ByOK3vjFD75aPcg!-145788764">
<input type="text">
</form>
四、Cookie和Session的关系图示
图片来源于网络,侵权请联系我。。。。。。。。
Cookie和Session的对比
- Cookie 只能存储 ASCII 码字符串,而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选 Session;
- Cookie 存储在浏览器中,容易被恶意查看。考虑安全性时首选 Session。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密;
- 对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。
- 单个 Cookie 保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie ,而Session无所谓。