持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
什么是cookie
- 是服务器保存在浏览器的一个文本信息
- 大小很小,只有
4KB - 浏览器每次发送请求,都会将
cookie里的数据带上 - 一般我们用它来保存一些状态信息:(登录状态,购物车信息等)
cookie其实并不是一个理想的客户端储存机制,因为大小很小,且不具有数据操作的的接口,一般我们会使用Web Storage Api和IndexdDB
web Storage Api其实就是我们常说的:localStorage和sessionStorage
IndexDB:是一个浏览器数据库
每一个Cookie都有以下几个部分
Cookie名字Cookie的数据- 到期时间(超过这个时间,就会失效)
- 所属域名(一般默认为当前域名)
- 生效路径(一般为当前路径)
举例:
当用户下想访问
www.examlpe.com,那么这个时候,服务器就会在浏览器写入一个cookie
cookie的域:www.example.comcookie的路径:/
假设cookie的生效路径设置为/home,那么也就意味之,这个cookie只可以访问www.example.com/home
在之后浏览器访问相关的服务器时,就会将该域名和路径都对的上的,且cookie没有失效的cookie发送给服务器
浏览器的同源政策规定:在相同域名的cookie是可以共享的,就是它不考虑你的port和协议
Cookie和HTTP协议
cookie由http产生,也被http所使用
cookie的生成
我们可以在请求的响应头里面看到
我们拿bing主页进行演示,首先将原来有的cookie删除,避免缓存之类的
然后刷新,选择一个查看他的响应头
我们可以看到set-cookie,其实这就是服务器在给浏览器设置的cookie
并且我们还可以看到,其实一次HTTP回应中会设置多个cookie(包含了多个set-cookie字段)
举例:
Set-Cookie:foo=bar
那么其实我们就是设置了一个名为foo的cookie,它的值是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,这就是浏览器在向服务器发送cookie
我们还可以看到,其实cookie中有多个cookie,他们用;分隔
举例:
Cookie:foo = bar
意思就是:浏览器向服务器发送了名为foo的cookie,值为bar
一次发送多个cookie
Cookie:name1 = value1 ; name2 = value2; name 3 = value3
Cookie属性
Expires和max-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
Domain和Path
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保持一致
secure和http-only
secure
规定只有在加密
https协议下,这cookie才会发送给服务器
http-only
只有在浏览器发送
Http请求的时候,才会带上该cookie
并且使用了http-only,是无法使用js获取的,类似(document.domain等)
samesite
其实就是为了防止产生
CRFS攻击
CRFS攻击·:就是会去伪造带有我们正确的cookie信息的网络请求
samesite有三个属性值
- none
- strict
- lax
-
none:
chrome将lax设置为默认值,但是哦我们不需要这个
samesite属性,所以就需要显示的关闭一定需要设置
secure才会生效,也就是,你的cookie需要通过HTTPS才可以发送 -
strict
严格,不允许任何第三方的
cookie,也就是,只有当我们的url和请求目标一致时,才会发送过于严格,体验感不好
-
lax
也是不允许第三方的cookie,但是导航到目标的get请求除外
总结
cookie
- 大小很小,只有
4KB左右 - 由
http产生又被http使用set-cookie:服务器设置的cookie- cookie具有多个属性
- 截止时间:
max-age和expires - 协议:
http-only和secure CSRF:samesite- 范围:
domain和path
- 截止时间:
- cookie具有多个属性
Cookie:浏览器发送的cookie- 一次可以发送多个,之间用逗号分开
参考链接: