cookie和session

36 阅读4分钟

cookie

历史

HTTP是无状态协议,cookie的出现,可以标识由哪个用户发起请求。

类型

按网站划分

第一方cookie:相对于当前页面的域名同站。a.taobao.com和taobao.com都属于同站,即该域名的父级域名相同的都为同站。

第三方cookie:相对于当前页面的非同站。

按存储时间划分

session cookie也称临时cookie,仅为当前会话,浏览器关闭后才会消失,关闭当前页面不会,再次打开页面还是会存在。已做过test

local cookie也称持久cookie,为cookie的Expires/Max-age属性值决定

属性

  1. Name:此cookie名称。
  2. Value:此cookie值。
  3. Domain:默认为当前域名,只能自己使用,子域名都无法使用,在devtool中是不带.的域名(未验证)。仅能设置父域名或当前域名,设置域名后,子域名都可使用该cookie,在devtool中是带.的域名。
  4. Path:默认/,设置请求路径可带该cookie,请求的路径前面包含了Path,则会携带该cookie。
  5. Expires/Max-age:默认session,即当前页面关闭后失效。Expires指过期时间,Max-age指多少秒后过期,建议使用Max-age,但是会有兼容性问题,因为是HTTP1.1版本提出的;但是使用Expires的话,用户更改了系统时间,所以也会有问题,具体情况具体选择。
  6. Size:此cookie的大小,Name和Value的字符个数。
  7. HttpOnly:设置为true,则JS无法读取该cookie,只有发起请求才会携带该cookie。
  8. Secure:当协议为HTTPS默认开启;当协议为HTTP,而设置了Secure,浏览器会忽略。
  9. SameSite:用来限制第三方cookie,值有以下三种,
  • Strict:完全禁止第三方cookie。
  • Lax:默认值,只有导航到目标网址的GET请求可以携带cookie。
  • None:可以携带cookie,设置None条件是Secure必须设置。
导航请求类型示例StrictLaxNone
链接×
预加载×
GET表单×
  1. 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。

  1. Partition Key:
  2. 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的区别:

  1. cookie存储在客户端,session存储在服务器端
  2. cookie的大小为4kb,每个域名下可存放53个左右,session的大小无限
  3. cookie不安全,可以通过document.cookie获取,session比较安全,因为存储在服务端

第三方cookie的应用

广告

楼盘页面,嵌入了腾讯广告,加载广告SDK时,腾讯广告会set-cookie(每次只能设置一个cookie,但可设置多个set-cookie响应头)设置第三方cookie,cookie id,用来标识用户。用户点击广告链接,腾讯就知道用户从哪个页面进入了广告页,统计访问量,记录用户喜好与行为,为用户画像。每当这个用户浏览含有腾讯广告的页面时,就会去服务器找相关的用户信息,分析用户,给用户投放更精准的广告,提高广告点击率,购买率等。若没有这个cookie id,则认为是新用户访问。

广告cookie是基于浏览器创建id,用来标识用户。