cookie 面面观

概述

cookie 是什么? cookie 是浏览器和 Web 服务器之间的媒介,通过用户请求在两者之间传递一些不太重要但具有标记作用的信息。
为什么需要 cookie? 众所周知,HTTP 是无状态的,如果 Web 浏览器想要记录用户当前会话等,就可以通过 cookie 传递数据。
cookie 有哪些限制? cookie 定位为一小段文本信息,一般大小不超过 4K。每个浏览器对于每个域名下 cookie 个数的限制也不同,但类似 Safari,个数就不受到限制。如果超出限制,有可能无法写入或老 cookie 被剔除。
cookie 怎么用? 综上所述,cookie一般用于存储少量不重要数据(cookie
过于庞大,会使得 HTTP 请求头变得臃肿,存储隐私数据有被窃取的风险),由 Web 服务器写入浏览器,浏览器会在以后每次 Web 请求中带入请求头中。

cookie 的类型

cookie 分为 session cookie持久化 cookie。区别在于过期时间和用途,前者当用户退出登录或关闭浏览器时即消失,用于记录用户登录状态;后者用于存储其他不重要信息,过期时间较长,当用户手动清除或者到达过期时间时才消失。

cookie 的首部

cookie 有两个版本 - 版本 0 和版本 1,现代浏览器普遍使用版本 0 (由 Netscape 公司提出),故此处只介绍版本 0 。
我们先来看 chrome 浏览器下 baidu.com 的 cookie。

baidu.com 的 cookie

注意到共有 9 个字段,分别代表含义如下:

cookie 字段

在介绍个字段具体内容之前我们先来看 Web 服务器向浏览器发送 cookie 的数据格式:

Set-Cookie:  userId=123456; 
             domain='a.baidu.com';
             path=/auto;
             expires=2017-06-17T23:40:56.000Z;   
             secure=true|false;
             sameSite=Lax|Strict

userId 即该 cookie 的名称,对应的值为 123456,不过不建议对数据明文展示,还是要对 cookie 进行加密。
domain 即该 cookie 的作用域名。域名分为多级,如果设置 domain=baidu.com,那么访问 baidu.com 后缀时都会发送该 cookie,如果设置 domain=tieba.baidu.com,那么在访问 baidu.com 时则不会带上该 cookie。
path 即作用路径,类似 domain 的逻辑,与之共同作用。设置 domain=tieba.baidu.com; path=/,访问 tieba.baidu.com 下所有的路径,都会把该 cookie 带入请求头。如果设置 domain=tieba.baidu.com; path=/gk,则访问 tieba.baidu.com/gk时才会发送。
expires/max-age 即过期时间。此处就对应前文说到的两种 cookie 类型。expires 的值是一个时间戳,max-age 的值是到过期时间的时间长度,以秒为单位。为什么会有两个值呢?原因在于,有时候客户端和服务器端的时间不一致,设置具体的时间点并没有意义。这个字段的值经常和缓存搭配使用,后面会说到。
size 即 cookie 的大小,这个字段通常是浏览器自己填写的,不需要用户干涉。
http 即该 cookie 是否在 http 访问时发送,对应 secure 字段 -- 是否只允许在 SSL 访问时发送。
samesite 目前只有 Chrome 和 FireFox 支持,是谷歌开发的一种安全机制,用于阻止 CSRF 和 XSS 攻击的一个手段,具体就不展开了,详见 参考[4]。

注意:关于域名分级又是一个话题,有时间可以另开一文详述

cookie 的工作原理

讲了这么久的废话,终于步入正题了。所以,cookie 到底是如何工作的呢?请看下图,<u>浏览器每次向服务端发起请求时,都会同时传递符合条件的所有 cookie 值</u>,所以不建议在 cookie 中放置较大的数据,这样请求会变得臃肿,影响传输效率:

客户端和服务端的基情全靠 cookie

cookie 的增删改查

新增/查询

浏览器本身不提供 cookie 的操作接口,为了方便操作,通常会把 cookie 操作封装起来。原始状态通过 document.cookie 能拿到的是所有没有设置 HTTP 字段的 cookie 值:

console.log(document.cookie);
"name1=value1; name2=value2"

浏览器端 设置 cookie 的操作是把一个 cookie 字符串赋值给 document.cookie 对象:

const cookie = 'token=123456; path=/writer; max-age=0';
document.cookie = cookie;
// 'token=123456; path=/writer; max-age=0'
console.log(document.cookie);
//'name1=value1; ..., token=123456'

服务器端浏览器端 设置 cookie 是通过 响应首部 完成的:
javascript
Set-Cookie: name=value; max-age=1000;

#### 删除/更新
需要对 cookie 对象进行更新操作时,在 **浏览器端** 通过覆写键值对完成:
```javascript
document.cookie = 'token=12345';
console.log(document.cookie);
// 'token=12345'
document.cookie = 'token=23456';
console.log(document.cookie);
// 'token=23456'

删除操作只需要将 expires 字段或者 max-age 字段设置为立即过期或者过去时间即可:

document.cookie = 'token=123456';
console.log(document.cookie);
// 'token=12345'
document.cookie = 'token='',max-age=0';
// or
document.cookie = 'token='',expires=Thu, 29 Jun 2017 15:55:06 GMT';
console.log(document.cookie);
// ''

服务器端 同理,�同样是 Set-Cookie 首部,设值规则同浏览器端一致。

Cookie 与会话

由于 Cookie 在每次请求中都会传递到服务器端,所以一般会存储 Session 标识,每次访问会带上 session_id 等标记用户登录态的信息,服务端验证存在才可以进行进一步操作,否则判断为未登录。下图中的 session_id 的 cookie 就可以认为是会话保持关键字。

session cookie

Cookie 与缓存

Cookie 的 max-ageexpires 字段的值不为空且有效时,即响应头中有 Set-Cookie 字段时,响应的主体即文件资源等默认是可以进行缓存的,而这个缓存控制需要配合 no-control 等字段进行,具体另开一文详述。

参考

[1]. cookie 限制
[2]. 细说 Cookie
[3]. 再见,CSRF:讲解set-cookie中的SameSite属性
[4]. <HTTP 权威指南>
[5]. <图解 HTTP>
[6] <JavaScript 高级程序设计>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容