Cookie

Cookie是储存在浏览器的一小段的数据,用来记录在关闭浏览器、刷新页面以及关闭页面的时候需要保存下来的数据,以及为了辨别用户身份而存储在用户本地终端上的数据。
可以使用 document.cookie 查看当前页面的Cookie。
具体使用场景是:

  • 会话状态管理:如用户登陆、购物车、游戏分数等需要记录的信息
  • 个性化设置:如用户自定义设置、主题等
  • 浏览器跟踪行为:分析用户行为等

cookie最大内存为4k,由一个名称(value)和一个值(key)和其他控制Cookie有效期、安全性、使用范围的可选属性组成。

Cookie工作过程

  • 客户端发送HTTP请求到服务器
  • 当服务器收到HTTP请求时,在响应头里面添加一个 set-Cookie 字段。
  • 浏览器收到响应后保存下 Cookie。
  • 之后对该服务器每一次请求中都通过Cookie字段将Cookie信息发送给服务器。

图片如下:

image.png
图1

image.png
图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!如:

  1. //bilibili.com
  2. document.cookie = "user = jeff"
  3. //a.bilibili.com 子域名
  4. console.log(document.cookie) // 没有“user = jeff”

解决办法需要显性的设置,如下:

  1. //bilibili.com
  2. document.cookie = "user = jeff;domain = a.bilibili.com" //同理,把a.bilibili.com换成baidu.com,那么baidu.com这个域名就可以访问这个cookie了
  3. //a.bilibili.com 子域名
  4. console.log(document.cookie) // 没有“user = jeff”

path

设置路径下的页面可以访问cookie,必须是绝对路径,默认为当前路径。例如:

  1. 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,如:

  1. let data = new Date(Date.now() + 86400e3)
  2. let time = data.toUTCString();
  3. document.cookei = "expires="+time
  • max-age

wxpires 的代替选项,设置方法为当前时间与过期时间之间的秒数,同理时间为过去的时间,会被删除。例如我想一个小时后就删除,如下:

  1. //cookie一个小时后删除
  2. document.cookie = "max-age=3600"
  3. //立即删除
  4. document.cookie = "max-age=0"

HTTPOnly

设置该属性可以有效防止黑客的XSS攻击,作用是可以防止客户端脚本通过 document.cookie 等方式访问Cookie!

secure

作用是Cookie只能被通过HTTPS传输。
默认情况下,如果在 http://bilibili.com 下设置cookie,那么 https://bilibili.com 也能访问该cookie,反之亦然!
也就是说cookie默认是不区分协议的!

如果一个cookie包含绝对不能通过未加密的HTTP协议发送敏感内容,那么就应该设置这个选项:

  1. 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不兼容旧版本。