客户端存储小作品

257 阅读4分钟

客户端储存

知识要点

  • 在 koa 中 cookie 的使用方式
  • 客户端 cookie 的使用方式
  • localStorage 及 sessionStorage 使用
  • 各种本地存储的异同

目标

  • cookie 在服务端及客户端的使用方式
  • 会使用 localStorage 及 sessionStorage 做数据的持久化
  • 了解各种本地存储的异同

客户端储存方案

  • 服务端储存

    • 服务端文件储存
    • 内存
    • 数据库:mysql、mongoodb、Oracle等等。
  • 客户端储存(离线储存)

    • 浏览器

cookie

  • cookie 是http 协议下,服务端或者脚本可以维护客户端信息的一种方式。

  • koa 中 cookie 的使用

    • 储存cookie的值;
    ctx.cookies.set(name, value, [options])
    
    • 获取cookie的值
    ctx.cookies.get(name, [options])
    
    • options常用设置
      • maxAge 一个数字表示从 Date.now() 得到的毫秒数
      • expires cookie 过期的 Date
      • path cookie 路径, 默认是'/'
      • domain cookie 域名
      • secure 安全 cookie 设置后只能通过https来传递cookie
      • httpOnly 服务器可访问 cookie, 默认是 true
      • overwrite 一个布尔值,表示是否覆盖以前设置的同名的 cookie (默认是 false). 如果是 true, 在同一个请求中设置相同名称的所有 Cookie

登录案例

  • 验证用户名密码是否正确;

  • 实现登录功能,通过记住我实现七天免登录;

router.get("/login", async (ctx, next) => {
    let cookieInfo = ctx.cookies.get("isLogin")
    if (cookieInfo) {
        let serverInfo = md5("张三" + "123");
        if (serverInfo == cookieInfo) {
            ctx.redirect("/list");
        }
    }
    await ctx.render("login.pug");
})

router.post("/checkUser", (ctx, next) => {
    // console.log(ctx.request.body);
    //假定用户名是张三 密码是123;
    if (ctx.request.body.username == "张三" && ctx.request.body.pwd == "123") {
        console.log(ctx.request.body);
        if (ctx.request.body.memberMe) {
            //需要储存登录成功的状态;
            let loginStatus = md5("张三" + "123");
            ctx.cookies.set("isLogin", loginStatus, {
                maxAge: 3600 * 1000 * 24 * 7
            })
        }
        //跳转到list页面;
        ctx.redirect("/list");
    } else {
        //用户名或者密码错误,跳转到错误页面;
        ctx.redirect("/error");
    }
})

rememberMe.jpg

  • cookie查询

cookie.jpg

通过本地 cookie 实现记录换肤功能

main.jpg

main-changeColor.jpg

  • 客户端cookie使用方式;

    • 设置

      document.cookie="key=value"
      
      • key 和 value 是包含在一个字符串中

        • key 包含字段
          • [name] 这个name为自己取的cookie名称,同名的值会覆盖
          • domain 所属域名
          • path 所属路径
          • Expires/Max-Age 到期时间/持续时间 (单位是秒)
          • http-only 是否只作为http时使用,如果为true,那么客户端能够在http请求和响应中进行传输,但时客户端浏览器不能使用js去读取或修改
      • 多个key=value使用 ; (分号)分隔

    • 获取

      document.cookie
      

      返回值是当前域名下的所有cookie,并按照某种格式组织的字符串 :key=value;key1=value1;......keyn=valuen

    • 封装

      • 设置cookie封装
      //设置cookie
      function setCookie(name,value,options={}){
          let cookieData = `${name}=${value};`;
          for(let key in options){
              let str = `${key}=${options[key]};`;
              cookieData += str;
          }
          document.cookie = cookieData;
      }
      
      • 获取cookie
      //获取Cookie
      function getCookie(name){
          let arr = document.cookie.split("; ");
          for(let i=0;i<arr.length;i++){
              let items = arr[i].split("=");
              if(items[0]==name){
                  return items[1];
              }
          }
          return "";
      }
      
    • 几种皮肤背景色

      ["white","rgb(204,232,207)", "rgb(200,200,169)", "rgb(114,111,128)"]
      
      let colorArr = ["white","rgb(204,232,207)", "rgb(200,200,169)", "rgb(114,111,128)"];
      let key = 0;
      if(getCookie("key")){
           key = getCookie("key");
      }
      if(localStorage.getItem("key")){
          key = localStorage.getItem("key");
      }
      document.body.style.background = colorArr[key];
      document.querySelector(".changeSkin").onclick = function(){
          key++;
          key = key>3?0:key;
          setCookie("key",key,{
               "Max-Age":3600*24
          });
          localStorage.setItem("key",key);
          document.body.style.background = colorArr[key];
      }
      

客户端操作cookie特点

  • 浏览器会主动存储接收到的 set-cookie 头信息的值
  • 有时效性;
  • 可以设置 http-only 属性为 true 来禁止客户端代码(js)修改该值

本地缓存Storage

  • localStorage 及 sessionStorage 使用

    • 设置

      setItem(key, value) 添加或更新(如果数据项中已存在该key)数据项中指定key的value

    • 获取

      getItem(key) 获取数据项中指定key对应的value

    • 移出指定数据

      removeItem(key) 删除数据项中指定key的value

    • 清空所有数据

      clear() 清空所有数据项

通过storage来改造换肤功能

let colorArr = ["white","rgb(204,232,207)", "rgb(200,200,169)", "rgb(114,111,128)"];
    let key = 0;
    if(localStorage.getItem("key")){
        key = localStorage.getItem("key");
    }
    document.body.style.background = colorArr[key];
    document.querySelector(".changeSkin").onclick = function(){
        key++;
        key = key>3?0:key;
        localStorage.setItem("key",key);
        document.body.style.background = colorArr[key];
    }

通过storage实现添加歌曲列表功能

  • 通过stroage来处理本地多开音乐页面得问题;
  • 实现删除及删除所有列表的功能;

本地存储异同

  • 共同点

  • localStorage 和 sessionStorage 和 cookie 共同点

    • 同域(同源策略)限制:同源策略:请求与响应的 协议、域名、端口都相同 则时同源,否则为 跨源/跨域
    • 存储的内容都会转为字符串格式
    • 都有存储大小限制
  • localStorage 和 sessionStorage 共同点

    • API 相同

    • 存储大小限制一样基本类似

    • 无个数限制

  • 不同点

  • localStorage

    • 没有有效期,除非删除,否则一直存在
    • 同域下页面共享
    • 支持 storage 事件
  • sessionStorage

    • 浏览器关闭,自动销毁
    • 页面私有
    • 不支持 storage 事件
  • cookie

    • 浏览器也会在每次请求的时候主动组织所有域下的cookie到请求头 cookie 中,发送给服务器端
    • 浏览器会主动存储接收到的 set-cookie 头信息的值
    • 可以设置 http-only 属性为 true 来禁止客户端代码(js)修改该值
    • 可以设置有效期 (默认浏览器关闭自动销毁)(不同浏览器有所不同)
    • 同域下个数有限制,最好不要超过50个(不同浏览器有所不同)
    • 单个cookie内容大小有限制,最好不要超过4000字节(不同浏览器有所不同)

小结:

  1. 需要兼容到极低版本的浏览器(懂的都懂),那么肯定使用Cookie了
  2. 少量的用户状态数据,且有会话性Cookie需求,Cookie会更好
  3. 大容量的存取,选Storage
  4. 需要持久化缓存,localStorage
  5. 只需要在当前页面使用的数据,sessionStorage

github地址