cookie
历史
HTTP是无状态协议,cookie的出现,可以标识由哪个用户发起请求。
类型
按网站划分
第一方cookie:相对于当前页面的域名同站。a.taobao.com和taobao.com都属于同站,即该域名的父级域名相同的都为同站。
第三方cookie:相对于当前页面的非同站。
按存储时间划分
session cookie也称临时cookie,仅为当前会话,浏览器关闭后才会消失,关闭当前页面不会,再次打开页面还是会存在。已做过test
local cookie也称持久cookie,为cookie的Expires/Max-age属性值决定
属性
- Name:此cookie名称。
- Value:此cookie值。
- Domain:默认为当前域名,只能自己使用,子域名都无法使用,在devtool中是不带.的域名(未验证)。仅能设置父域名或当前域名,设置域名后,子域名都可使用该cookie,在devtool中是带.的域名。
- Path:默认/,设置请求路径可带该cookie,请求的路径前面包含了Path,则会携带该cookie。
- Expires/Max-age:默认session,即当前页面关闭后失效。Expires指过期时间,Max-age指多少秒后过期,建议使用Max-age,但是会有兼容性问题,因为是HTTP1.1版本提出的;但是使用Expires的话,用户更改了系统时间,所以也会有问题,具体情况具体选择。
- Size:此cookie的大小,Name和Value的字符个数。
- HttpOnly:设置为true,则JS无法读取该cookie,只有发起请求才会携带该cookie。
- Secure:当协议为HTTPS默认开启;当协议为HTTP,而设置了Secure,浏览器会忽略。
- SameSite:用来限制第三方cookie,值有以下三种,
- Strict:完全禁止第三方cookie。
- Lax:默认值,只有导航到目标网址的GET请求可以携带cookie。
- None:可以携带cookie,设置None条件是Secure必须设置。
导航请求类型 | 示例 | Strict | Lax | None |
---|---|---|---|---|
链接 | × | ✔ | ✔ | |
预加载 | × | ✔ | ✔ | |
GET表单 | × | ✔ | ✔ |
- SameParty:设置后,可以将一些域名集合都作为第一方cookie。
例子:需要对.taobao.com、.tmall.com、.alimama.com设置为第一方cookie。
step1:需要在taobao.com,tmall.com,alimama.com三个服务器的/.well-know/first-party-set文件
// www.taobao.com/.well-know/first-party-set 组长角色
{
"owner": ".taobao.com",
"members": [".tmall.com", ".alimama.com"]
}
// www.tmall.com/.well-know/first-party-set
{
"owner": ".taobao.com"
}
// www.alimama.com/.well-know/first-party-set
{
"owner": ".taobao.com"
}
step2:设置cookie时,需要设置SameParty属性
解析步骤:
已设置set-cookie: id=userid; SameParty; Secure; SameSite=Lax; domain=.taobao.com
当访问www.tmall.com,向.taobao.com发起请求,会携带该cookie。
注意:设置SameParty必须是Secure和SameSite不为strict;要求域名需要在同一个主体下;owner只有一个;域名只能属于一个成员members。
- Partition Key:
- Priority:
cookie的唯一性由Name,Domain和Path决定
注意:
1.F12中显示的cookie是当前页面加载时写入的cookie,所以可以看到有其他站的cookie,cookie写入时,会在对应的域名下进行存储,但是也会会在当前页面上进行存储,所以加载页面时,可以看到其他站的cookie。
问题:
1.客户端如何封装一个读取,删除,设置cookie的类?
// 获取
function getCookie(name) {
// document.cookie只能获取当前页面域名下cookie的name和value
const cookies = document.cookie
const list = cookies.split(';')
const res = {}
list.forEach((item) => {
const arr = item.split('=')
const name = arr[0].trim()
const value = arr[1]
res[name] = value
})
return res[name]
}
// 删除,设置cookie的max-age=0,或者expires设置为过去时间
function deleteCookie(name) {
const cookies = document.cookie
const list = cookies.split(';')
for(let i = 0; i < list.length; i++) {
const arr = list[i].split('=')
const cName = arr[0].trim()
if (cName === name) { // 删除cookie,注意cookie的唯一性与name,domain,path有关,需要删除的话,需要知道这些信息,而document.cookie只能知道name,value
document.cookie = `${list[i];Max-age=0;}`
break;
}
}
}
// 设置/修改
function setCookie(name, value, expires) {
// document.cookie一次只能设置一个cookie
document.cookie = `${name}=${value};expires=${expires};`
}
session
Session也是一个服务端用来记录用户状态的机制。Session对象是客户端第一次请求数据时创建,也是以key-value键值对存在。
cookie和session的区别:
- cookie存储在客户端,session存储在服务器端
- cookie的大小为4kb,每个域名下可存放53个左右,session的大小无限
- cookie不安全,可以通过document.cookie获取,session比较安全,因为存储在服务端
第三方cookie的应用
广告
楼盘页面,嵌入了腾讯广告,加载广告SDK时,腾讯广告会set-cookie(每次只能设置一个cookie,但可设置多个set-cookie响应头)设置第三方cookie,cookie id,用来标识用户。用户点击广告链接,腾讯就知道用户从哪个页面进入了广告页,统计访问量,记录用户喜好与行为,为用户画像。每当这个用户浏览含有腾讯广告的页面时,就会去服务器找相关的用户信息,分析用户,给用户投放更精准的广告,提高广告点击率,购买率等。若没有这个cookie id,则认为是新用户访问。
广告cookie是基于浏览器创建id,用来标识用户。