Cookie
Cookie是储存在浏览器的一小段的数据,用来记录在关闭浏览器、刷新页面以及关闭页面的时候需要保存下来的数据,以及为了辨别用户身份而存储在用户本地终端上的数据。
可以使用 document.cookie
查看当前页面的Cookie。
具体使用场景是:
- 会话状态管理:如用户登陆、购物车、游戏分数等需要记录的信息
- 个性化设置:如用户自定义设置、主题等
- 浏览器跟踪行为:分析用户行为等
cookie最大内存为4k,由一个名称(value)和一个值(key)和其他控制Cookie有效期、安全性、使用范围的可选属性组成。
Cookie工作过程
- 客户端发送HTTP请求到服务器
- 当服务器收到HTTP请求时,在响应头里面添加一个
set-Cookie
字段。 - 浏览器收到响应后保存下 Cookie。
- 之后对该服务器每一次请求中都通过Cookie字段将Cookie信息发送给服务器。
图片如下:
图1
图2
Cookie的属性
上图的图2,Cookie的属性有:
- Name / Value
- Domain
- Path
- Expires / Max-Age
- Size
- HttpOnly
- Secure
- SameSite
需要说明的如下:
Domain
可访问Cookie的域。默认情况下,cookie只有在设置的域下才能被访问。例如,如果我在 bilibili.com
下设置了Cookie,那么 baidu.com
是不能获取这个Cookie。
问题是,默认情况下, bilibili.com
下的子域名也不能访问该Cookie!如:
//bilibili.com
document.cookie = "user = jeff"
//a.bilibili.com 子域名
console.log(document.cookie) // 没有“user = jeff”
解决办法需要显性的设置,如下:
//bilibili.com
document.cookie = "user = jeff;domain = a.bilibili.com" //同理,把a.bilibili.com换成baidu.com,那么baidu.com这个域名就可以访问这个cookie了
//a.bilibili.com 子域名
console.log(document.cookie) // 没有“user = jeff”
path
设置路径下的页面可以访问cookie,必须是绝对路径,默认为当前路径。例如:
document.cookei = "path=/admin" //路径下的/admin这个页面,可以访问该cookie。
通常,我们只需要把 path=/
设置为根路径,该网站的所有页面都可访问!
expires,max-age
这两个作用是一样的,如果不设置这两个属性其中一个,那么在浏览器关闭会话时,cookie就会被删除,这样的情况下这样的cookie被称为session cookie!
为了让cookie在浏览器关闭后依然存在,就需要设置这两个属性之一:
- expires
用法: expires=Tue, 19 Jan 2038 03:14:07 GMT
,cookie一但到期,就会自动删除,或者时间为零以及负数,也会被删除。设置这个属性必须采用GMT时区的这种格式。可以使用 data.toUTCString
,例如我想设置一天后就删除cookie,如:
let data = new Date(Date.now() + 86400e3)
let time = data.toUTCString();
document.cookei = "expires="+time
- max-age
是 wxpires
的代替选项,设置方法为当前时间与过期时间之间的秒数,同理时间为过去的时间,会被删除。例如我想一个小时后就删除,如下:
//cookie一个小时后删除
document.cookie = "max-age=3600"
//立即删除
document.cookie = "max-age=0"
HTTPOnly
设置该属性可以有效防止黑客的XSS攻击,作用是可以防止客户端脚本通过 document.cookie
等方式访问Cookie!
secure
作用是Cookie只能被通过HTTPS传输。
默认情况下,如果在 http://bilibili.com
下设置cookie,那么 https://bilibili.com
也能访问该cookie,反之亦然!
也就是说cookie默认是不区分协议的!
如果一个cookie包含绝对不能通过未加密的HTTP协议发送敏感内容,那么就应该设置这个选项:
document.cookie = "secure";
SameSite
可以让Cookie在跨站请求的时候不会被发送,有效防止CSRF。
:::info 关于跨站知识:
- 跨站与跨域是不一样的,跨域是在同源策略下的一种方案,判断同源的方法是协议、主机名、端口号。
- 而跨站,比跨域的判断条件宽松一些,只需要两个URL的eTLD+1相同即可,不需要考虑协议和端口号。
- eTLD表示有效域名,例如.con,.co.uk,。github.io等。
- eTLD+1表示,有效顶级域名+ 二级域名,例如taobao.com等。
举例子:
- www.taobao.com 与 www.baidu.com 跨站
- www.a.taobao.com 与 www.b.taobao.com 同站。
- .a.taobao.com 与 b.taobao.com 跨站。 :::
有三个值:
- Strict:在跨站的情况下,cookie永远都不会发送
- Lax:与Strict类似,但多加了一个例外,以下两个条件成立,就会发送:
- HTTP是安全的,例如使用的是GET方法而不是POST
- 该操作执行顶级导航。
- None
- 无论是否跨站,都是发送cookie
需要注意的是,在旧版本的浏览器中,None是默认值,新版本Lax是默认值。而Strict不兼容旧版本。