[面试复盘]谈谈你对cookie的理解

274 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情

什么是cookie

  • 是服务器保存在浏览器的一个文本信息
  • 大小很小,只有4KB
  • 浏览器每次发送请求,都会将cookie里的数据带上
  • 一般我们用它来保存一些状态信息:(登录状态,购物车信息等)

cookie其实并不是一个理想的客户端储存机制,因为大小很小,且不具有数据操作的的接口,一般我们会使用Web Storage ApiIndexdDB

web Storage Api其实就是我们常说的:localStoragesessionStorage

IndexDB:是一个浏览器数据库

每一个Cookie都有以下几个部分

  • Cookie名字
  • Cookie的数据
  • 到期时间(超过这个时间,就会失效)
  • 所属域名(一般默认为当前域名)
  • 生效路径(一般为当前路径)

举例:

当用户下想访问www.examlpe.com,那么这个时候,服务器就会在浏览器写入一个cookie

  • cookie的域:www.example.com
  • cookie的路径:/

假设cookie的生效路径设置为/home,那么也就意味之,这个cookie只可以访问www.example.com/home

在之后浏览器访问相关的服务器时,就会将该域名和路径都对的上的,且cookie没有失效的cookie发送给服务器

浏览器的同源政策规定:在相同域名的cookie是可以共享的,就是它不考虑你的port协议

CookieHTTP协议

cookiehttp产生,也被http所使用

cookie的生成

我们可以在请求的响应头里面看到

我们拿bing主页进行演示,首先将原来有的cookie删除,避免缓存之类的

然后刷新,选择一个查看他的响应头

setCookie.png

我们可以看到set-cookie,其实这就是服务器在给浏览器设置的cookie

并且我们还可以看到,其实一次HTTP回应中会设置多个cookie(包含了多个set-cookie字段)

举例:

Set-Cookie:foo=bar

那么其实我们就是设置了一个名为foocookie,它的值是bar

set-cookie不仅可以设置cookie的值,还可以设置cookie多个属性,多个属性间用号分隔,且无次序要求

Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly

如果服务器想要改变cookie,就是patch类似,那么必须保证key,domain,secure,path全部匹配,只要有一个不一致,那么都是put,就是会重新设置一个新的cookie

举例:

Set-Cookie: key1=value1; domain=example.com; path=/blog

你想要改变cookie值,那么你必须使用相同的set-cookie

Set-Cookie: key1=value2; domain=example.com; path=/blog

假如你设置为

Set-Cookie: key1=value1; domain=example.com; path=/

那么你就会新建一个cookie,并且它只对www.example.com生效

cookie的发送

服务器给浏览器cookie以后,那么每次请求,浏览器都会带上域名相同,路径相同,且没有失效的cookie

再次拿bing主页举例

cookie发送.png

我们可以在请求标头里面看到cookie,这就是浏览器在向服务器发送cookie

我们还可以看到,其实cookie中有多个cookie,他们用;分隔

举例:

Cookie:foo = bar

意思就是:浏览器向服务器发送了名为foocookie,值为bar

一次发送多个cookie

Cookie:name1 = value1 ; name2 = value2; name 3 = value3

Cookie属性

Expiresmax-Age

都和到期时间有关

  • Expires:指定了一个具体的到期时间:当到达这个时间的时候,浏览器就不再保留这个cookie
  • max-age:指定从cookie开始存在的秒数,max-age的优先级更高

拿bing主页的一个cookie举例:

Set-Cookie: fpc=AmQiYzUk3T9JmANktmQVQjKCeMQLAwAAAPLE6doOAAAA; expires=Thu, 24-Nov-2022 11:56:08 GMT; path=/; secure; HttpOnly; SameSite=None

Expires

指定的是到期时间,值的格式是UTC(世界协调时间)格式,要想转换为我们一般的时间**,我们可以使用Date.prototype.toUTCString(),将我们现在的时间改为UTC时间**

大概意思就是,拿中国举例,我们在东八区,所以时间快了8小时:UTC时间与北京时间换算 (datetime360.com)

你可能也会发现,一些cookie中并没有设置Expires,那么就说明,他只在当前session有效,你页面一关闭,就需要重新获取cookie

另外:其实cookie的过期时间不是准确遵守的,因为浏览器是通过当地时间来判断是不是过期的,但是转化为UTC总会有误差,所以,不一定还在服务器指定的时间就失效

max-age

设置的从cookie设置到cookie消失的秒数,超过时间,立刻就被删除

假如你既没有设置cookie,有没有设置max-age,那么你相当于一个session cookie,也就是,你浏览器页面一关闭,浏览器不会帮你保留这个cookie

DomainPath

domain

从上面的描述,我们其实可以知道,如果我们处于相同的域名,那么其实我们的cookie是可以进行共享的,那么domain就是来设置,你是不是要共享这个cookie的

看上面那个例子:我们因为没有设置domain属性,所以,我这个cookie就是不共享的,也就是我的子域名下面是获取不到这个cookie的

Set-Cookie: esctx=AQABAAAAAAD--....; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None

在这个cookie中,他设置了domain,也就是,我浏览器访问服务器,会去判断这个domain是不是满足cookie设置的domain,那么请求的时候带上这个cookie

path

大概意思就是,假如我这个path是后续我需要请求的路径开头一部分,那么我就会带上这个cookie

现在path:/,那么意思就是,下次你/home的时候,他这个cookie也是会带着的,当然前提条件是domain保持一致

securehttp-only

secure

规定只有在加密https协议下,这cookie才会发送给服务器

http-only

只有在浏览器发送Http请求的时候,才会带上该cookie

并且使用了http-only,是无法使用js获取的,类似(document.domain等)

samesite

其实就是为了防止产生CRFS攻击

CRFS攻击·:就是会去伪造带有我们正确的cookie信息的网络请求

samesite有三个属性值

  • none
  • strict
  • lax
  1. none:

    chrome将lax设置为默认值,但是哦我们不需要这个samesite属性,所以就需要显示的关闭

    一定需要设置secure才会生效,也就是,你的cookie需要通过HTTPS才可以发送

  2. strict

    严格,不允许任何第三方的cookie,也就是,只有当我们的url和请求目标一致时,才会发送

    过于严格,体验感不好

  3. lax

    也是不允许第三方的cookie,但是导航到目标的get请求除外

总结

cookie

  • 大小很小,只有4KB左右
  • http产生又被http使用
    • set-cookie:服务器设置的cookie
      • cookie具有多个属性
        • 截止时间:max-ageexpires
        • 协议:http-onlysecure
        • CSRF:samesite
        • 范围:domainpath
    • Cookie:浏览器发送的cookie
      • 一次可以发送多个,之间用逗号分开

参考链接:

浏览器模型 - Cookie - 《阮一峰 JavaScript 教程》 - 书栈网 · BookStack