目录
定义
cookie 是后端可以存储在用户浏览器中的小块数据!
cookie 最常见用例包括用户跟踪,个性化以及身份验证。
cookie的相关信息
以百度的打开界面为例,查看一下cookie的相关信息,如下图:
一条cookie就存在12个相关配置信息
Doamin
Domain: 表示cookie能够作用的主机地址(域名);
tips: Domain里面不携带协议和端口,但是cookie的部分属性只有在https协议下才有效(Secure字段相关)
-
Domain字段的值:
通过上图可以看到有的域名前面带有.
,有的域名前面不加.前面加点的表示该cookie既可以作用于当前域名又可以作用于其子域名 ,不加点表示该cookie仅仅作用于当前域名
-
默认值:若是没有显示设置Domain,则浏览器会自动截取
当前url的host
作为Domain的值
当前页面的域名为 www.baidu.com在当前页面设置cookie ⇒ document.cookie=‘test=11111’
可以看到默认的域名为当前页面的host -
可以设置的域名
我想修改cookie的Domain为localhost ==> document.cookie=‘test=11111; Domain=localehost’, 发现cookie的Domain值无变化原因是
在子域里面可以给父域设置cookie,其余不可互相设置!
www.baidu.com与localhost之间毫无关联,因此不可互相设置为其Domain那么此时我将域名设置为baidu.com, document.cookie=‘test=11111; Domain=baidu.com’
此时发现域名值变为.baidu.com(设置成功)
tips: 只有Name/Domain/Path值都一致,才会被认为是同一cookie才会被覆盖,其余情况会被认为是不同cookie
Path
Path: 表示在当前路径后面拼接哪些路径可以使用此cookie
- 默认值: / 表示当前路径后面拼接任何路径都可以使用此cookie
- 举例说明 在a.com/a 这个页面设置了一个cookie 这个cookie的path= /a 那么在a.com/a这个页面可以拿到这个cookie但是在a.com/b这个页面就拿不到cookie
注:在a.com/a/b还是可以拿到这个cookie的
Expires/Max-age
expirse: 在指定时间失效; 若是设置的时间为过去的时间则表示立即删除这个cookie
max-age:多少秒之后失效。若是负值则表示立即删除这个cookie
都存在:max-age
的优先级更高一点
都不存在:session(会话)cookie,在浏览器关闭时cookie失效(关闭当前页面不会失效)
tips:这里显示的时间要加8个小时才是北京时间
HttpOnly
HttpOnly字段为true表示该cookie无法使用js获取和操作,仅能通过浏览器或服务器来控制。
这个字段为true的cookie一般是用来存储一些与用户身份相关的信息或安全凭证的!
使用这个字段可以避免用户的关键信息被盗用
Secure
这个字段为true表示该cookie 只能在 协议为https的协议中使用
若是协议为http的请求,则这个cookie会被自动忽略!
samesite
samesite可以 限制跨站
请求时cookie的发送,该字段只有在跨站请求的时候才会起作用!
samesite的值一共有四种情况
-
None: 不论是否跨站都发送cookie
注:虽然约束性最弱,但是只有在协议为https时才有效 而且必须带有Secure字段 否则会有 橙色感叹号标志 -
Lax:部分情况下携带cookie
-
Strict: 跨站不携带cookie
使用js操作cookie
获取cookie
document.cookie可以获取部分cookie相关信息(HttpOnly为false的字段)
document.cookie.split(';')
获取到的值为
[
'BIDUPSID=E0494A9A74FC1B360707B6185A210ABE',
' PSTM=1679652950',
' BAIDUID=E0494A9A74FC1B368E290637135810DB:FG=1',
' BD_UPN=123253',
' BAIDUID_BFESS=E0494A9A74FC1B368E290637135810DB:FG=1',
' BD_HOME=1',
' ZFY=Kg6ntAWGkfjwXZ5ocPZXZENPOSJeX2IcPgSR4yMqnYs:C',
' H_PS_PSSID=36545_38105_38470_38439_38468_38289_36806_37925_38383_26350_38423_37881',
' BA_HECTOR=0ga081aka1a1a4040k842kf11i27ng41m']0: "BIDUPSID=E0494A9A74FC1B360707B6185A210ABE"1: " PSTM=1679652950"2: " BAIDUID=E0494A9A74FC1B368E290637135810DB:FG=1"3: " BD_UPN=123253"4: " BAIDUID_BFESS=E0494A9A74FC1B368E290637135810DB:FG=1"5: " BD_HOME=1"6: " ZFY=Kg6ntAWGkfjwXZ5ocPZXZENPOSJeX2IcPgSR4yMqnYs:C"7: " H_PS_PSSID=36545_38105_38470_38439_38468_38289_36806_37925_38383_26350_38423_37881"8: " BA_HECTOR=0ga081aka1a1a4040k842kf11i27ng41m"
]
添加/修改一个cookie
- 使用
document.cookie='key=value ...'
语法添加或修改cookie- 若是不存在此字段(或name/domain/path任意字段不同),则添加cookie
- 若是存在此字段(且
name/domain/path
三个字段都相同),则修改cookie值
- 在添加过程中,除了Name字段是必须设置的,其余字段都可以不设置,若是不设置值,那么这些字段的默认值是什么呢?
在上述代码中我在添加cookie时仅仅设置了cookie的name与value字段其他字段都没有设置,通过下属图片可以看到其他字段的默认值document.cookie='test='
- Value: 默认为空
- Domain: 默认为当前url的host
- Path: 默认为/
- Expires/Max-Age: 默认为会话(浏览器关闭失效)
- HttpOnly: 默认为false
- Secure: 默认为false
- SameSite: 默认为空
- 举例说明
document.cookie='test=111' document.cookie='test=111; max-age=7000' document.cookie='test=111; max-age=7000; path=/web/search' // 设置无效,因为当前url为/web 所以浏览器会默认忽略这条cookie; 此时打开url='/web/search'会发现存在此cookie
删除cookie
document.cookie = 'key=;max-age=-1'
通过添加max-age等于一个负值
,则该字段就会在cookie面板消失
插件js-cookie
- 下载
npm install --save js-cookie
- 使用
存储cookieimport Cookies from 'js-cookie'
获取cookieCookies.set(name, value) Cookies.set(name, value, { expires: 7, path:'' })
删除cookie// 获取带有指定name的cookie Cookies.get(name) // 获取所有cookie Cookies.get()
// 删除指定名称的cookie Cookies.remove(name) // value // 删除带有路径的cookie Cookies.remove(name, { path: '' })
服务端设置cookie
服务端可以在响应头中通过 set-cookie
字段设置cookie。设置格式如下
Set-Cookie: Name=Value
在请求响应后,浏览器会自动检查response中是否存在cookie,若是存在会自动添加在浏览器的application中的cookie中。在发送请求时会自动携带符合条件
的cookie!
需要注意的是,在跨域情况下设置的set-cookie默认情况下会被浏览器忽略。
跨域情况下前端获取不到cookie
如上图,我在响应头中看到后端返回的cookie,但是在浏览器的application中的Cookies里并没有看到此cookie;
原因:因为我是在本地调试,产生了跨域 -> 在跨域情况下set-cookie默认情况下会被浏览器忽略。
解决:
- 服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。
- 响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名
- ajax需要指定withCredentials为true
本地调试解决跨域问题导致cookie不能携带的问题
跨站与跨域
跨域
先了解一下跨域,简单来说就是协议名、域名、端口号只要有一个不一致
则被称为跨域!
跨站
先了解一下域名,只要是顶级域名与一级域名一致
就不跨站,若是顶级域名或一级域名不一致则被称为跨站!