Cookie工作在客户端。
1991 年 HTTP 0.9 诞生了,当时只是为了满足大家浏览 Web文档的需求 ,所以只有 GET 请求,浏览完了就走了,客户端与服务器端两个连接之间是没有任何联系的,这也是 HTTP 为无状态的原因,因为它诞生之初就没有这个需求。
但随着交互式 Web 的兴起(所谓交互式就是你不光可以浏览,还可以登录,发评论,购物等用户操作的行为),单纯地浏览 Web 已经无法满足人们的要求,比如随着网上购物的兴起,需要记录用户的购物车记录,就需要有一个机制记录每个连接的关系,这样我们就知道加入购物车的商品到底属于谁了,于是 Cookie 就诞生了。
什么是 Cookie
Cookie 是服务器发送到用户浏览器并保存在本地的一小部分文本信息,格式为 key/value的形式,由用户(客户端)浏览器暂时或永久保存。它会在浏览器下次向同一服务器再发起请求时被携带(请求头中)并发送到服务器端。
Cookie 的特点
- Cookie 具有保质期
即有永久的也有临时的,每当发送请求的时候,都会根据域名来携带(请求头中)相应的cookie,可通过设置expires 、max-age来设定保存日期,不设置的话默认是临时存储,即关闭浏览器就消失。 - Cookie 安全性
Cookie在本地可以被更改,用户可以随时清理Cookie,每次发送请求时以明文携带在请求头中,因此安全性差,建议敏感数据不存储在Cookie中。 - Cookie 存储大小受限制
Cookie有个数和大小的限制,不同的浏览器每个域名下,有不同的cookie条数限制,20-50条不等,大多数的浏览器限制大小一般为4kb,超出会删除旧的Cookie。 - Cookie 受同源策略限制
只能访问当前域名下的Cookie,禁止跨域访问Cookie。 - Cookie 自动传送给服务器端
Cookie会在浏览器下次向同一服务器再发起请求时被携带(请求头中)并发送到服务器端,服务器将获取到发送Cookie数据。
浏览器发起请求时在请求头中携带Cookie(Cookie: xxxxxx
):
为什么会有Cookie
Web应用程序是使用HTTP协议传输数据的,HTTP 请求都是无状态的,一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接,因此服务器不知道客户端是谁,访问过多少次(类似每次都是初次见面)。但是我们的 Web 应用通常都需要知道发起请求的人是谁。为了解决这个问题,HTTP 协议设计了一个特殊的请求头:Cookie。服务端可以通过响应头(set-cookie)将少量数据响应给客户端,浏览器会遵循协议将数据保存,并在下次请求同一个服务的时候带上(浏览器也会遵循协议,只在访问符合 Cookie 指定规则的网站时带上对应的 Cookie 来保证安全性)。
Cookie应用场景
Cookie 主要用于以下三个方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
注意:当前浏览器基本上全面兼容 localstorage ,Cookie 基本上只会作为会话状态管理 存储登录信息。
操作Cookie
Cookie在实际工作中,主要是Web服务器开发人员经常使用,而前端开发人员一般不使用使用Cookie,如需将数据存储在本地一般使用HTML5的本地存储功能。
设置Cookie方式:
- 服务器端通过响应设置
- 客户端通过JavaScript设置
Cookie属性列表
要操作Cookie,我们需要了解Cookie支持的属性。
属性 | 名称 | 描述 |
---|---|---|
Name | 名称 | 用于指定Cookie的名称(格式为 key/value,可理解为键名key),同域名下Name不能重复,Name不建议用中文 |
Value | 内容 | 用于指定Cookie的内容(值Value) |
Domain | 所属域名 | 用于指定Cookie的所属域名,默认是当前域名,Cookie不能跨域写入、读取,Cookie默认存储在本域,也可以存储在本域的父级域名、根域之下 |
Path | 生效路径 | 用于指定Cookie的生效路径,默认是当前路径,其他路径无法读取这个Cookie,一般而言,都是存储到根目录,即/目录 |
Expires | 到期时间 | 用于指定cookie过期的时间。如果是显示未来的某个时间点,该条 cookie 会在这个时间点失效,如果是显示着为 session 或者 /,证明该条 cookie 在浏览器关闭之后,就会失效 |
Max-Age | 有效期 | 用来指定Cookie有效期,比如60 60 24 * 365(即一年31536e3秒) |
HTTP | 是否仅用于传输。如果该栏目为勾选状态,说明该条Cookie是 JS 无法读取、写入的,只能通过服务器进行读写 | |
Size | 大小 | Cookie 内容的大小,默认byte |
Secure | 是否仅适用于https,如果此项勾选,该条 cookie 仅在 https 下才能生效 | |
SameSite | 是否防止跨域发送。 |
打开 Chrome浏览器的开发者工具,可以看到当前Cookie:
服务器端操作Cookie
服务器端向客户端发送Cookie是通过HTTP响应报文实现的,在响应头添加Set-Cookie
设置需要给客户端发送的Cookie数据,格式如下:
Set-Cookie: "name=value;domain=.domain.com;path=/;expires=Sat, 11 Jun 2016 11:29:42 GMT;HttpOnly;secure"
如,在Eggjs框架中,设置Cookie:
ctx.cookies.set('name', 'value',{ path:'/' });
服务器端通过响应头(Set-Cookie: xxxx
)给用户浏览器保存Cookie:
如,在Eggjs框架中,读取Cookie:
// 读取全部Cookie
ctx.cookies
// 读取指定Key的Cookie
ctx.cookies.get(key, options)
客户端JavaScript操作Cookie
推荐:基于jQuery封装的用于读取、写入和删除 Cookie插件库
读取
在JavaScript中,通过 document.cookie
,即可获取当前域名全部可以JavaScript操作的Cookie信息,只是形式为字符串,没条数据按分号隔开,需要使用JavaScript处理才能获取到指定Key的Cookie值。
写入
document.cookie="userId=828; userName=hulk; domian=demo.com; path=/; expire="+xxx;
Cookie 可以同时写入多条,必填项为 key = value
,其余属性为选填项。
修改
与写入一样的设置方式
document.cookie="userId=828; userName=hulk; domian=demo.com; path=/; expire="+xxx;
注意:修改部分的内容,但是之前的属性 如path、domain,都需要与之前属性保持统一,否则不是修改,而是写入一个新的。
删除
将Cookie 重新写入,过期时间为现在,或者现在之前的某个时间点即可实现删除。