一、Cookie

1. Cookie是什么

Cookie是由服务器端生成,发送给User-Agent,浏览器会将Cookie的key/value自动保存到某个目录下的文本文件内,下次请求同一网站时就自动发送该Cookie给服务器。

目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。

cookie默认根据域名自动判断是否带上cookie信息访问。

2. Cookie 应用场景

场景一:避免重复登录

当我们打开一个网站时,如果这个网站我们曾经登录过,那么当我们再次打开网站时,发现就不需要再次登录了,而是直接进入了首页。

场景二:权限验证

由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

3. Cookie的组成

一般情况下,cookie是以键值对进行表示的(key-value)的字符串

请添加图片描述

cookie常用属性:

  • name:String cookie的名称,Cookie一旦创建,名称便不可更改。
  • value:Object cooke的值
  • path:String Cookie的使用路径, “/”
  • expires/maxAge:int cookie的有效时间,单位秒。默认为–1,浏览器关闭即失效。
  • domain:String 可访问该Cookie的域名,注意第一个字符必须为“.”。
  • secure:Boolean Cookie是否仅被使用安全协议传输,安全协议。
    注意:浏览器提交Cookie时只会提交name与value属性。

cookie特点:

  • Cookie的不可跨域名
  • cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
  • 由于在HTTP请求中的cookie是明文传递的,所以安全性成问题。(除非用HTTPS)
  • Cookie的大小限制在4KB左右。对于复杂的存储需求来说是不够用的。

4. Cookie 的生命周期

cookie有2种存储方式,一种是会话性,一种是持久性。

  • 会话性:如果cookie为会话性,那么cookie仅会保存在客户端的内存中,当我们关闭客服端时cookie也就失效了
  • 持久性:如果cookie为持久性,那么cookie会保存在用户的硬盘中,直至生存期结束或者用户主动将其销毁。
    cookie我们是可以进行设置的,我们可以人为设置cookie的有效时间,什么时候创建,什么时候销毁。

5. Cookie使用方法

a. 客户端 Cookie

JavaScript 可以使用 document.cookie 属性来创建 、读取、及删除(覆盖) cookie。

document.cookie 将以字符串(名/值对的形式展示)的方式返回所有的 cookie,类型格式如下:

document.cookie="
  username=John Doe; 
  expires=Thu, 18 Dec 2043 12:00:00 GMT; 
  path=/
";

document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";

注意:从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过期。

Cookie 方法的封装

docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
docCookies.getItem(name)
docCookies.removeItem(name[, path], domain)
docCookies.hasItem(name)
docCookies.keys()

1.设置 cookie 值的函数

docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])

示例:

let setCookie=(key, value, days) =>{
    let now = new Date();
    let expires = '';
    let formatValue = '';
    if(days){
       now.setTime(now.getTime() + days * 24 * 60 * 60 * 1000);
        expires = ";expires=" + now;
       }
    if(!key){
       return false
    }
    try{
        formatValue  = JSON.stringify(value);
    }catch(e){
        console.log(e);
        return false;
    }
    document.cookie = key + "=" + formatValue + expires;
}

2.获取 cookie 值的函数

let getCookie=key=> {
    //如果cookie中有数据  才可以获取数据
    if (document.cookie) {
      let cookieInfo = document.cookie;
      //cookie中可能会包含一些 额外的数据,这些数据特点是由   分号和空格间隔的
      //所以 先将 分号和空格  替换掉   替换成  ;
      let arr = cookieInfo.replace(/;\s/g, ';').split(";");
      let item,brr
      for (let i = 0; i < arr.length; i++) {
        item = arr[i].split("=");
        if (item[0] === key) {
          brr = item[1];
          return JSON.parse(brr);//如果找到 我们想要的键,将值转成数组返回
        }
      }
      //如果cookie中 没有我们想获取的键值,直接返回一个空数组
      return [];
    }
    //如果cookie中没有数据,直接返回一个空数组
    return [];
}

3.移除 cookie 值的函数

let removeCookie=key=> {
    setCookie(key, "", -1);
}

4.检测 cookie 值的函数

docCookies.hasItem(name)

5.获取所有的cookie的列表

docCookies.keys()

返回一个这个路径所有可读的cookie的数组。

function setCookie(name, value, path, domain, secure,expire){
  if(!expire){
     expire = expire*24*60*60;//365Ìì
  }
  var Days = 365; //cookie ½«±»±£´æ 365 Ìì
  var exp  = new Date();    //new Date("December 31, 9998");
  exp.setTime(exp.getTime() + expire*1000);
  document.cookie = 
     name + "=" + escape(value) + 
     ("; expires=" + exp.toGMTString() ) +
     ((path) ? "; path=" + path : "") +
     ((domain) ? "; domain=" + domain : "") +
     ((secure) ? "; secure" : "");
}
  
function getCookie(name){
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
     begin = dc.indexOf(prefix);
     if (begin != 0) return null;
  } else {
     begin += 2;
  }
  var end = document.cookie.indexOf(";", begin);
  if (end == -1) {
     end = dc.length;
  }
  return unescape(dc.substring(begin + prefix.length, end));
}

function deleteCookie(name, path, domain){
  if (getCookie(name)){
     document.cookie = name + "=" +
     ((path) ? "; path=" + path : "") +
     ((domain) ? "; domain=" + domain : "") +
     "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}

b.响应 Cookie

response对象提供的Cookie操作方法只有一个添加操作。

response.addCookie(cookie); 要想修改Cookie只能使用一个同名的Cookie来覆盖原来的Cookie,达到修改的目的。删除时只需要把maxAge修改为0即可。

function getCookieByName(name) {
   const cookie = document.cookie;
   return cookie.split(`; ${name}=`).pop().split(';').shift();
}

6. Cookie的HTTP传输

7. HTTP请求 表示

客户端把cookie发送到服务器:

注意:游览器只会携带在当前请求的url中包含了该cookie中path值的cookie。并且以key:value的形式进行表示。多个cookie用进行隔开。

请添加图片描述

8. HTTP响应 表示

服务器发送cookie给客户端:

HTTP响应中, cookie的表示形式是,Set-Cookie:cookie的名字,cookie的值。如果有多个cookie,那么在HTTP响应中就使用多个Set-Cookie进行表示。

请添加图片描述

Cookie的不可跨域名

Cookie在客户端是由浏览器来管理的。

Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。

隐私安全机制能够禁止网站非法获取其他网站的Cookie。

Unicode编码:保存中文

中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。

提示:Cookie中保存中文只能编码。一般使用UTF-8编码即可。不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码。

BASE64编码:保存二进制图片

Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。例如在Cookie中使用数字证书,提供安全度。使用二进制数据时也需要进行编码。

注意:本程序仅用于展示Cookie中可以存储二进制内容,并不实用。由于浏览器每次请求服务器都会携带Cookie,因此Cookie内容不宜过多,否则影响速度。Cookie的内容应该少而精。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐