一个HTTP cookie 是一个存储数据的方式,它是由服务端发送到客户端的。
浏览器会存储它,并会在下一次发起请求的时候携带cookie。(如果是命中了domain、path等字段)
cookie是纯文本格式,不包含任何可执行的代码。
cookie 使用目的
- session 管理
- 用户设置管理(Personalization)
- 跟踪用户行为(Tracking)
生成cookie
cookie是由服务端返回的响应头来设置的,以分号分隔:
1 | Set-Cookie: <cookie-name>=<cookie-value> |
cookie 编码
原始规范中明确指出只有三个字符必须进行编码:分号、逗号和空格,规范中还提到可以进行URL编码,但不是必须的。
对于name=value
格式,通常对name
和value
分别进行编码,而不对等号=
进行编码操作。
支持选项
大小写不敏感
- Expires 和 Max-Age
- Secure:只能使用HTTPS请求,该选项只是一个标志而没有值
- HttpOnly:cookie不能使用JavaScript访问
- Domain 和 Path
- SameSite:两个可选值:strict 和 lax
1 | Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly |
Expires & Max-Age
紧跟cookie值后面的每个选项都以分号和空格分开。Expires
和Max-Age
指定了cookie何时不会再发送至服务器,随后浏览器将删除该cookie。(时间是根据系统时间来计算的)
1 | Set-Cookie: name=value; Expires=Wed, 27 Mar 2019 05:03:33 GMT |
在没有设置expires
和Max-Age
的情况下,cookie的生命周期仅限于当前会话中,关闭浏览器意味着这次会话的结束,所以会话cookie仅存在于浏览器打开状态下。
如果expires
设置了过去的一个时间点,那么这个cookie会被立即删除。
如果Max-Age
设置了0,这个cookie也会被立即删除。
Domain & Path
Domain
和Path
字段指定了cookie的作用域:即cookie应该发送给哪些URL
Domain
标识符指定了哪些主机可以接收cookie。如果不指定,默认为当前主机(不包含子域名)document.location
,如果指定了Domain
,则一般包含子域名。
Path
指定了主机下什么路径可以接收cookie。子路径也会被匹配。
Domain
只能设置为当前消息头主机名的一部分,同样Path
设置的路径要存在于当前请求URL。不合法的Domain
选择将直接被忽略。
需要注意的是,只有在 domain 选项核实完毕之后才会对 path 属性进行比较。同时,如果设置
Path=/blog
也会匹配/blogrool
Secure
默认情况下,在HTTPS链接上传输的cookie都会被自动添加上secure
选项
维护
如果需要改变cookie的值,需要发送给另外一个具有相同name
、domain
、path
的Set-Cookie
消息头,这将覆盖原来的cookie值
cookie标识:name-domain-path-secure
Expires
和Max-Age
不是标识符的一部分,所以需要修改cookie的值的时候不需要重新指定过期时间。
如果修改了任一选项,则会新创建一个cookie。发送到服务器的cookie会根据
Path
来排序,Path
越详细cookie越靠前。
自动删除
cookie会被浏览器自动删除:
- 会话cookie
- 持久化cookie过期
- cookie数量达到上限,浏览器删除
限制条件
有一些浏览器如ie会限制cookie的数量
发送给服务器的所有cookie最大值为4KB,所有超过限制的cookie都会被截断并且不会发送至服务器。
SubCookies
1 | Set-Cookie: name=a=b&c=d&e=f |
在单个cookie中保存多个name-value
键值对
HttpOnly
不能通过 JavaScript 设置
HttpOnly
选项,因为不能再通过 JavaScript 读取这些 cookie
操作方法
document.cookie
navigator.cookieEnabled
一旦 cookie 通过 JavaScript 设置后便不能提取它的选项,所以你将不能知道
Domain
,Path
,Expires
日期或Secure
标记。
使用document.cookie
可以向使用Set-Cookie
一样将cookie赋值即可,标识符一致的cookie会被修改