存储sessioncookiestorage

1. session:

  • 概念:

    • 是一个数据对象,用来存储信息。
    • 是一个抽象对象,指代多个有关联的http请求所构成的一个会话。多次请求之间能够共享一些信息。
  • 实现:

    • 在每个请求的参数或者数据中带上相关的信息。不受 cookie 限制,但是受到 请求长度的限制。
    • 用 cookie 存储,可以是整个session 的具体数据,也可以是 session的标识(sessin_id).
  • 特点:

    • 只存在与 服务端。
    • 并不是 服务器 原生支持的。是中间件自己创建并管理的。
    • session 仅仅是一个对象信息,可以存到 cookie ,也可以存到任何地方(如内存,数据库)。
    • 存到哪,可以开发者自己决定,只要实现一个 store 对象,提供 set,get 方法即可。
    • session_id,是唯一的标识 session 的,以及其他一些必要信息会放在 cookie 中,一起返回到前端。
    • 其他信息,可以保存在 session_id 命名的文件中。
  • session 的负面影响:

    • 性能影响。如果用户很多,信息都保存在 sessin 文件中,查找耗时太多(可以分目录和哈希等)。可以自己实现session,将session信息存放到数 据库当中,这样做最好对数据库进行一下缓存的设置了,不然对上千万的数据进行太频繁的检索,也是蛮耗资源的。
  • session 的清除:

    • 定期清理 session(清除服务端的 session 文件,和 客户端的 cookie 信息)
    • cookie, expires 设置为 负值,客户端的cookie 信息就会过期,浏览器就会自动删除。
  • koa-session 的 原理:【有空一定要看看源码,看源码要注意命名、特色、知识点的学习。也会学习 koa 插件的写法的过程】【看源码,要先有整体把控图,然后逐步去分析啊】

    • 使用流程:

      • app.use(session(CONFIG, app)); // 初始化koa-session中间件
      • let n = ctx.session.views || 0; // 每次都可以取到当前用户的session
    • 初始化的时候,把 session 对象挂载在 app.context上。所以后面可以 从 ctx.session 上获得 session
    • 在接到 http 请求的时候,
    • 默认把数据 json ,塞进了 cookie ,即 cookie 来存储加密后的 session 信息。
    • 如果设置了外部 store ,会调用 store.set() 去保存 session 。具体的保存逻辑,保存到哪里,由 store 对象自己决定!
    • 用 cookie 存储的时候,对session(包含过期时间)序列化后做一个简单的base64编码。
    • 就算信息保存在文件中,还是必不可少的需要 cookie
    • session_id 的默认实现是 一个时间戳加随机字符串。
    • koa-session允许用户在config中配置自己的编码和解码函数,因此完全可以使用自定义的加密解密函数对session进行编解码
  • session 的鉴权过程:

    • 用户登录的时候,服务端生成一个会话和一个id标识
    • 会话id在客户端和服务端之间通过cookie进行传输
    • 服务端通过会话id可以获取到会话相关的信息,然后对客户端的请求进行响应;如果找不到有效的会话,那么认为用户是未登陆状态
    • 会话会有过期时间,也可以通过一些操作(比如登出)来主动删除
  • token 的典型流程:

    • 用户登录的时候,服务端生成一个token返回给客户端
    • 客户端后续的请求都带上这个token
    • 服务端解析token获取用户信息,并响应用户的请求
    • token会有过期时间,客户端登出的时候也会废弃token,但是服务端不需要任何操作
  • session 和 token 的区别:

    • session, 要求服务端存储信息,并根据id能够检索,而 token 不需要。
    • 服务端 要 通过 token 来解析 用户身份,也需要定义好相应的协议。
    • session 一般使用cookie 来交互。token,可以是 cookie,也可以是 其他heaser,甚至可以放在请求的内容中。不使用cookie可以带来跨域的便利性
    • 很多情况下,sessin 和 token 可以一起使用。
  • token 是如何生成的呢?

    • 一般由第三方服务来提供。
  • 参考:

    • https://www.cnblogs.com/woodk…

      • 看源码的时候,可以画一下 主要模块的脑图,更有助于理解。
    • https://www.cnblogs.com/longh…
    • https://www.jianshu.com/p/8f4…
    • https://segmentfault.com/a/11…

2. cookie

  • 存储大小:每条的存储空间为4k;
  • 特点:

    • cookie没有显示的删除函数,可以设置expire过期事件,自动触发浏览器的删除机制。
    • 服务器通过设置响应头来设置客户端的cookie,Set-Cookie: cookie-名=cookie值。可以同时添加多个Set-Cookie,从而设置多个cookie的值。
    • 不允许存储敏感信息(用户名,密码等),一定要存储,要设置 cookie为 httponly, 另外考虑使用 非对称加密
    • cookie 通常与 session 一起使用。

      • 登录时,server 端存储 用户信息相关的 session。
      • server 端,生成的 sessionid 会放在cookie中,对应域名下就有了这个cookie。
      • 以后会自动带这个 cookie,server 根据id 找到 session,获取用户信息。
  • 设置cookie:

        document.cookie="userId=828";
        document.cookie="userName=hulk"; 
        此时浏览器将会维护两个cookie,分别为userId和userName;相当于:
        document.addCookie("userId=828");
        document.addCookie("userName=hulk");
        如果要改变一个cookie的值,只需重新赋值,例如:
        document.cookie="userId=929";
  • 获取cookie:

    var strCookie=document.cookie;
    console.log(strCookie); //userId=828; userName=hulk
    • 只能一次获取所有的cookie的值,而不能指定cookie名称来获得指定的值。
    • 如果在某个页面创建了一个cookie,那么该页面所在目录中的其他页面也可以访问该cookie。
    • 为了控制cookie可以访问的目录,需要使用path参数设置cookie。document.cookie=”userId=320; path=/shop”;就表示当前cookie仅能在shop目录下使用。
  • 常用的cookie操作及其函数实现:

    • addCookie(name, value, expireHours):
        function addCookie(name,value,expireHours){
             var exdate = new Date();    
            exdate.setTime(exdate.getTime() + expireHours * 60 * 60 * 1000);    
              document.cookie = name + "=" + escape(value) + ((expireHours == null) ? "" : ";expires=" + exdate.toUTCString());
        }
        toUTCString() 方法可根据世界时 (UTC) 把 Date 对象转换为字符串,并返回结果。
    • getCookie(name):
        function getCookie(name){
            let arr, reg = new RegExp(`^| ${name} = [^;]*;|$`);
            if (arr = document.cookie.match(reg)) return arr[2];
            else return null;
        }
  • cookie的可选项:

    • expires/max-age: 设置过期时间。expires是绝对时间,max-age是相对时间。如果没有设置过期时间,则表示是一个会话期cookie,在关闭浏览器后,会被移除。浏览器支持会话恢复,保留cookie。
    • domain和path:path,设置必须匹配的路径或者子路由才会发送cookie。domain标识指定了哪些主机可以接受cookie。如果没有设置,则是当前主机(不包含子域名),否则为设置的域名(包含子域名)。
    • secure和httponly:secure标志cookie只能通过https传输,可以防止xss攻击。httponly表示cookie无法通过javascript调用,防止中间人劫持。把cookie设置为secure,只保证 cookie 与服务器之间的数据传输过程加密,而保存在本地的 cookie文件并不加密。如果想让本地cookie也加密,得自己加密数据。
    • samesite:可以设置 SameSite:SameSite=Strict SameSite=Lax。则 cookie 不跨域发送。ajax中设置xhr.withCredentials = true;
  • 问题:

    • 问题:“www.qq.com” 与 “sports.qq.com” 公用一个关联的域名”qq.com”,我们如果想让”sports.qq.com” 下的cookie被 “www.qq.com” 访问:
    • 解答:我们就需要用到cookie 的domain属性,并且需要把path属性设置为 “/“。例:document.cookie = “username=Darren;path=/;domain=qq.com“
    • 问题:同域名的资源请求时,会默认带上本地的cookie,如何优化?
    • 解答:将静态资源分组,分别放在不同的子域下(子域名请求时,是不会带上父级域名的cookie的)

3. session 和 cookie 对比:

4. localStorage:

  • 存储大小:一般浏览器支持的是5M大小,不同浏览器会有所不同。
  • 是H5的新特性,兼容性不是很好。
  • 目前所有的浏览器都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换。
  • localStorage在浏览器的隐私模式下是不可读取的。
  • localStorage 本质上是对字符串的读取,如果存储内容多,会消耗内存空间,会导致页面变卡。
  • localStorage不会被爬虫抓取到。
  • localStorage只支持string类型的存储。一般我们会将JSON存入localStorage中,但是在localStorage会自动将localStorage转换成为字符串形式。这个时候我们可以使用JSON.stringify()这个方法,来将JSON转换成为JSON字符串。读取之后要将JSON字符串转换成为JSON对象,使用JSON.parse()方法:

    let storage = window.localStorage;
    let data = {
          name: 'aaa',
          sex: 'man',
          hobby: 'program'
    };
    let dataString = JSON.stringify(data);
    storage.setItem('data', dataString);
    let json = storage.getItem('data');
    let jsonObj = JSON.parse(json);
    console.log('json', json);
    console.log('jsonObj', jsonObj);
    console.log('dddd', typeof jsonObj);
  • 方法和属性:

    • 添加键值对:setItem(key, value);
    • 获取键值对:getItem(key);
    • 删除键值对:removeItem(key);
    • 清除所有键值对:clear();
    • 获取键名称:key(index);
    • (属性)获取localStorage中保存的键值对的数量:length。
    • 获取键值对:
    for (let i = 0; i < localStorage.length; i++) {
        let key = localStorage.key(i);
        let value = localStorage.getItem(key);
    }
  • 事件:

    • storage事件:浏览器在localStorage数据变化(真正的发生变化)之后给你的一个通知。
    • 包含的属性:

      • storageArea: 表示存储类型(session或local)
      • key:发生改变项的key
      • oldValue:key的原值
      • newValue: key的新值
      • url: key 改变发生的URL(有些早期版本中使用的是uri属性)
    • 这个事件兼容性好像不好,要少用。
    • localStorage存储的数据是不能跨浏览器共用的,一个浏览器只能读取各自浏览器的数据,储存空间5M.
  • 如何实现两个标签页的数据交互:

    • 调用localStorage:

      • 在一个标签页里面使用 localStorage.setItem(key,value)添加(修改、删除)内容;在另一个标签页里面监听 storage 事件。即可得到 localstorge 存储的值,实现不同标签页之间的通信。
      • 将要传递的信息存储在cookie中,每隔一定时间读取cookie信息,即可随时获取要传递的信息。

5. localStorage 和 cookie 对比:

6. localStorage 和 sessionStorage 的区别:

  • localStorage属于永久性存储,而sessionStorage属于当前会话结束的时候,sessionStorage中的键值对会被清空。

7. 参考:

  • https://www.jianshu.com/p/e4e…
  • https://www.jianshu.com/p/e3d…
  • https://segmentfault.com/a/11…
  • https://segmentfault.com/a/11…
  • https://www.jianshu.com/p/707…

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理