cookie这样理解就对了

242 阅读3分钟

看完搞定cookie

作为一个工作两年多的前端新人,对cookie的认识一直没有好好的研究过,于是今天趁着周末决定把这一块搞个明白,这样以后再和后端讨论的时候,就可以自信起来了,哈哈哈哈。

首先什么是cookie呢?

cookie其实就是一些字符串,它一般来自后端响应报文,后端会通过Set-Cookie返回一个cookie,浏览器在收到这样的报文的时候,会把它的值存到浏览器中,之后cookie的值会根据Set-Cookie中设置的条件随着前端请求自动发送到后端服务器。

cookie是干什么用的?

随着web应用程序的发展,直接在客户端存储用户信息成为了一件必要的事情,cookie的诞生就是在这样的背景之下。cookie可以存储一些跟用户相关的数据,这样后端在收到前端请求之后就会发现其中携带的cookie是哪个用户,从而避免每次都要查询数据,做到更快响应。

cookie由什么组成?

截屏2023-07-02 08.42.39的副本.png 名称:唯一标识这个cookie的名称,cookie的名字必须经过URL编码。
:存储一些字符串值,一般就是跟用户信息有关的字符,必须经过URL编码。
:应该自动携带该cookie的域,比如www.abc.com, 就代表浏览器请求的域名是它的时候,就应该带上这个cookie,再比如设置为.abc.com, 表示对所有的abc.com的子域都应该携带该cookie。
路径:当浏览器请求的URL中包含这个路径时才会把cookie发送到服务器。比如,路径是www.abc.com/test 代表只有www.abc.com/test/ 或者www.abc.com/test/* 的可以携带这个cookie,www.abc.com 这个路径则无法携带该cookie。
过期时间:表示浏览器何时删除这个cookie,这个时间格式是GMT。当设置为过去的时间,会立即删除这个cookie。
安全标志:单独的secure表示,设置它后,只有在https请求中才会携带cookie。

cookie的特点?

1 cookie是和特定域绑定的,只有请求特定的域,浏览器才会携带它。
2 cookie的存储空间是有限制的,如每个cookie不能超过4k,每个域不超过20个cookie。
3 如果cookie数量超过单个域的上限,浏览器就会删除之前的cookie,IE和Opera会按照最少使用原则删除之前的cookie,Firefox好像会随机删除之前的cookie,因此为了避免不确定的结果,尽量不要超出这个限制。
4 如果创建的单个cookie超过最大4k限制,则该cookie会被静默删除,一个字符通常占用一个字节,如果使用多字节字符,则每个字符最多可能占用4个字节。

cookie的缺点?

会随着相应请求一直往返于服务器和浏览器之间,占用一定的带宽资源。有一定的被盗用风险,如跨站请求伪造攻击。

cookie在前端的获取和设置

前端使用BOM的document.cookie获取该页面中所有的有效cookie的字符串,以;分隔,如name1=value1;name2=value2;name3=value3
注意,所有的名和值都是经过URL编码的,因此必须使用decodeURIComponent()解码。document.cookie会设置新的cookie字符串,这个字符串在被解析后会添加到原有cookie中,设置document.cookie不会覆盖之前存在的任何cookie,除非设置了已有的同名的cookie。

document.cookie = encodeURLComponent("name") + "=" + encodeURLComponent("zhangsan") + "; domain=.abc.com; path=/";

// 封装设置cookie和读取cookie的方法

getCookie(name) {
  let cookieName = `${encodeURLComponent(name)}=`
  let startinx = document.cookie.indexOf(cookieName)
  let cookieValue = null
  if (startinx > -1) {
    let cookieEnd = document.cookie.indexOf(";", startinx)
    if(cookieEnd === -1) {
      cookieEnd = document.cookie.length
    }
    cookieValue = decodeURIComponent(document.cookie.substring(startinx + cookieName.length, cookieEnd))
    return cookieValue
  }
}

setCookie(name, value, expires, path, domain, secure) {
  let cookieText = `${encodeURLComponent(name)}=${encodeURLComponent(value)}`
  if(expires instanceof Date) {
    cookieText += `; expires=${expires.toGMTString()}`
  }
  if (path) {
    cookieText += `; path=${path}`
  }
  if (domain) {
    cookieText += `; domain=${domain}` 
  }
  if( secure ) {
    cookieText += "; secure"
  }
  document.cookie = cookieText
}

unsetCookie(name, path, domain, secure) {
  setCookie(name, "", new Date(0), path, domain, secure) // new Date(0)是1970年1月1日,零毫秒初始化的日期对象,设置为过去时间,浏览器会将该cookie删掉。
}