美文网首页HTML的自我修养js:数据存储
简述cookie 、localStorage和sessionSt

简述cookie 、localStorage和sessionSt

作者: 放风筝的小小马 | 来源:发表于2017-07-27 11:19 被阅读164次

    Web Storage规范

    是HTML5的一部分

    目的:克服由cookie带来的一些限制,当数据需要被严格的控制在客户端时,无须持续的将数据发回服务器。

    目标

    • 提供一种cookie之外的存储会话数据的途径
    • 提供一种存储大量可以跨session存在的数据的机制

    定义
    Web Storage规范包含两种对象的定义:sessionStorage和globalStorage**。这两个对象在支持的浏览器中都是以 window 对象属性 的形式存在的。
    注意:在使用之前记得查看其浏览器支持情况

    Storage类型

    Storage类型的方法:

    • clear(): 删除所有值
    • getItem(name): 根据指定的名字 name 获取对应的值
    • setItem(name, value): 为指定的name设置一个对应的值
    • key(index):获得index位置处的值的名字。
    • removeItem(name):删除name指定的键值对。
      还可以通过length属性来判断有多少键值对存放在Storage对象中

    注意: Storage类型只能存储字符串。非字符串的数据在存储之前会被转换为字符串

    sessionStorage对象

    sessionStorage 对象是存储特定于某个会话的数据,当页面被重新加载时其仍然存在,只有当浏览器被关闭或者当前页面被关闭时,数据才会被清除;可以理解为数据被存储在浏览器中,只有浏览器被关闭后,数据才会被清除,同时,如果浏览器支持,在浏览器崩溃并重启之后仍然可以访问存储与sessionStorage中的数据

    因为sessionStorage对象绑定于某个服务器会话,所以当文件在本地运行的时候是不可用的。

    存储在sessionStorage中的数据只能由最初给对象存储数据的页面访问到,其只针对于当前会话,所以对多页面应用有限制

    使用
    sessionStorage对象是Storage的一个实例,所以可以使用setItem()或者直接设置新的属性存储数据
    如:

    // 使用方法存储数据
    sessionStorage.setItem('name', 'Hexon');
    // 使用属性存储数据
    sessionStorage.book = 'Professional Javascript'; 
    
    // 使用方法读取数据
    var name = sessionStorage.getItem('name');
    // 使用方法读取数据
    var book = sessionStorage.book;
    
    // 通过key来迭代存储与sessionStorage中的键值
    for (var i = 0, len = sessionStorage.length; i < len; i++) {
      var key = sessionStorage.key(i);
      var value = sessionStorage.getItem(key);
      alert(key + '=' + value);
    }
    
    // 使用for-in循环迭代sessionStorage中的值
    for (var key in sessionStorage) {
      val value = sessionstorage.getItem(key);
      alert(key + '=' + value);
    

    不同的浏览器写入数据方面略有不同,FireFox和WebKit实现了同步写入,所以添加到存储空间中的数据是立刻被提交的。而IE的实现是异步写入数据,在设置数据和将数据写入磁盘之间可能有延迟

    总结:sessionStorage对象应该只用于针对会话小段数据存储。如果需要跨会话存储数据,那么localStorage或者globalStorage更合适

    globalStorage对象

    只用FireFox2中实现了globalStorage对象,主要目的是为了实现 跨会话存储数据,但有特定的访问限制。

    要使用globalStorage,首先要指定哪些域名可以访问该数据

    使用方法

    // 只针对 域名 wrox.com 的存储访问
    globalStorage['wrox.com'].name = 'hexon';
    var name = globaleStorage['wrox.com'].name;
    

    注意:

    • globalStorage对象不是Storage的实例,而具体的globalStorage['wrox.com'] 才是
    • 当使用 globalStorage[''].name = 'hexon'来存储数据时,表示任何人都可以访问,一定不要这样做,不安全
    • 对globalStorage空间的访问,是依据发起请求的页面的域名、协议和端口 来限制的;如使用https协议在wrox.com中存储了数据,那么通过http访问的wrox.com的页面将无法访问该数据
    • 如果事先无法确定域名,那么使用 location.host 作为属性名比较安全,表示页面必须来自于同一个域名、协议和端口,才可以访问
    • 如果不使用removeItem() 或者 delete 删除,或者用户未清除浏览器缓存,存储在globalStorage属性中的数据将会一直保存在磁盘上

    注意: globalStorage对象在修订过的HTML5规范中被localStorage对象所取代

    localStorage 对象

    localStorage对象在修订过的HTML5规范中作为持久保存客户端数据的方案取代了globalStorage

    与globalStorage不同,不能给localStorage指定规则,规则在HTML5规范中就被制定,要访问同一个localStorage对象,页面必须来自同一个域名(子域名无效)、同一种协议,在同一端口上,这相当于 globalStorage[location.host]

    localStorage是Storage类型的实例,因此可以像使用sessionStorage一样使用它

    同时, 为了兼容只支持globalStorage对象的浏览器,可以使用以下方式进行能力检测:

    function getLocalStorage() {
      if (tpyeof localStorage === 'object') {
         return localStorage;
      } else if (typeof globalStorage === 'object') {
         return globalStorage[location.host];
      }  else {
         throw new Error('Local Storage not available.');
      }
    }
    

    sessionStorage和localStorage的对比与使用

    概念

    这两者都是本地存储,均不会被发送到服务器端,其主要在生命周期上有比较明显的区别;localStorage的生命周期更长,没有过期时间,原则上要等到通过JavaScript将内容清除掉或者清空cookie时才会消失;而sessionStorage则在Browser或Tab被关闭时就会清空

    限制

    • 对于localStorage而言,大多数桌面浏览器会设置每个来源5MB的限制,具体依浏览器而异
    • 对于sessionStorage,也因浏览器而异,一般每个来源在2.5MB ~ 5MB 之间

    浏览器支持情况
    这两者都都需要浏览器的API支持,浏览器的支持情况如下:

    image.png

    使用
    通过window.localStoragewindow.sessionStorage这而两个对象进行操作

    以操作localStorage为例:

    • 从存储中获取值
      window.localStorage.getItem('key')
    function setStyles() {
      var currentColor = localStorage.getItem('bgcolor');
      var currentFont = localStorage.getItem('font');
      var currentImage = localStorage.getItem('image');
    
      document.getElementById('bgcolor').value = currentColor;
      document.getElementById('font').value = currentFont;
      document.getElementById('image').value = currentImage;
    
      htmlElem.style.backgroundColor = '#' + currentColor;
      pElem.style.fontFamily = currentFont;
      imgElem.setAttribute('src', currentImage);
    }
    
    • 在存储中设置值
      window.localStorage.setItem可以从存储中获取指定的数据项或者设置新的数据项,该方法接受两个参数——要创建/修改的数据项的键,和对应的值。
    function populateStorage() {
      localStorage.setItem('bgcolor', document.getElementById('bgcolor').value);
      localStorage.setItem('font', document.getElementById('font').value);
      localStorage.setItem('image', document.getElementById('image').value);
      setStyles();
    }
    
    • 通过 StorageEvent 响应存储的变化
      无论何时,storage对象发生变化时(即创建/更新/删除,重复设置相同的项不会触发,storage.clear()方法至多触发一次),都会触发StorageEvent事件
      window.addEventListener('storage', function(){});
      示例:
    window.addEventListener('storage', function(e) {  
      document.querySelector('.my-key').textContent = e.key;
      document.querySelector('.my-old').textContent = e.oldValue;
      document.querySelector('.my-new').textContent = e.newValue;
      document.querySelector('.my-url').textContent = e.url;
      document.querySelector('.my-storage').textContent = e.storageArea;
    });
    

    注意:在同一个页面内发生的改变不会起作用——在相同域名下的其他页面(如一个新标签或 iframe)发生的改变才会起作用。在其他域名下的页面不能访问相同的 Storage 对象。

    • 删除数据记录
      window.localStorage.removeItem():接收一个参数,要删除的数据项key值
      window.localStorage.clear():不接收参数,只是简单的清空域名对应的整个存储数据

    cookie

    起源: 最初由网景公司引入,用于在客户端存储回话信息

    工作方式:要求服务器对任意HTTP请求,在响应头中添加Set-Cookie 字段来设置cookie,在客户端接收到这个cookie信息之后,将其存储起来,在此之后,当客户端再给创建它的域名发送HTTP请求时,都会在HTTP头中添加cookie信息,服务器可以根据这个cookie信息来决定该用户可以执行哪些操作(例如:是否允许它进行访问)

    cookie的组成:
    cookie由浏览器保存在客户端计算机中,由以下几块信息组成:

    • 名称:cookie的名称,这是唯一的,且字符不区分大小写。注意:cookie的名称必须是经过URL编码的
    • :存储在cookie中的字符串值。注意:值必须经过URL编码
    • :cookie对于哪个域有效,所有向该域发送的请求中,都会包含这个cookie信息,如果没有设置,则这个域会被认作是设置cookie的那个域
    • 路径:对于域下的路径访问,会包含cookie信息
    • 失效时间
    • 安全标志

    一个服务器发给客户端的SetCookie信息,如下:

    HTTP/1.1 200 OK
    Content-type: text/html
    Set-cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com; path=/; secure
    Other-header: other-header-value
    

    Set-cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT domain=.wrox.com; path=/; secure
    这个Set-cookie的解释如下:

    • cookie名称: name
    • cookie的值:value (注意:值跟名称是不同的东西)
    • 失效时间:Mon, 22-Jan-07 07:10:24 GMT;(这是GMT时间)
    • 域名: .wrox.com
    • 路径: /
    • 安全标志: secure(只有当客户端通过SSH连接时,才可以传输该cookie)

    cookie的特点

    • 创建方式:是由服务器来创建 cookie 信息的
    • 存放位置:客户端接收到服务器的cookie信息之后,将其存放在客户端的计算机中
    • cookie个数限制:cookie是绑定在域名下的,因此每个域的cookie个数是有限的,不同浏览器的限制不同,一般为50个,chrome和safari没有硬性限制。
    • cookie尺寸限制:对于每个域下的cookie的尺寸限制为4K字节注意:是一个域下的所有cookie的总尺寸之和要小于4K字节,不是单个cookie的尺寸
    • 失效时间:默认情况下,浏览器会话结束时即将所有的cookie删除,但是,可以自己设置失效时间,当未到达失效时间时,cookie将一直保存在客户端计算机中,除非自己手动删除
    • cookie会被附加在每个http请求中,因此会增加流量
    • 安全标志:当指定后(通过Set-Cookie中添加 secure 关键字即可),cookie只有在使用SSL连接的时候才发送到服务器

    注意事项

    • cookie个数和尺寸的限制,超过限制后,不同的浏览器有不同的处理方式,因此,一定不要超过限制
    • 域、路径、失效时间和secure标志都是服务器给浏览器的指示,以指定何时应该发送cookie,这些参数不会作为发送给服务器cookie信息的一部分
    • cookie的名称是经过URL编码的,注意:是名称
    • Javascipt中处理cookie有些复杂,主要是接口不好用,即:document.cookie

    cookie的缺陷

    • cookie会被附加在每个http请求中,因此会无形中增加流量
    • 由于http请求中的cookie是明文传输,因此有安全问题(除非使用https),不要使用cookie存放重要的数据
    • cookie的大小限制是4kb,对于复杂的存储需求可能不够用

    cookie的使用

    • 获取cookie:document.cookie,通过该方法可以获取cookie
    • 删除cookie:设置document.cookie并不会覆盖cookie,除非设置的cookie的名称已经存在。那么就会对原cookie进行覆盖
      封装的cookie代码
    let CookieUtil = {
        get: (name) => {
          let cookieName = encodeURIComponent(name) + "=",
              cookieStart = document.cookie.indexOf(cookieName),
              cookieValue = null;
    
          if (cookieStart > -1) {
            let cookieEnd = document.cookie.indexOf(';', cookieStart);
            if (cookieEnd === -1) {
              cookieEnd = document.cookie.length;
            }
            cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
          }
    
          return cookieValue;
        },
        set: function (name, value, expires, path, domain, secure) {
          let cookieText = encodeURIComponent(name) + '=' +
                           encodeURIComponent(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;
        },
    
        // 删除cookie, 并没有直接的删除cookie的方法,这里通过重新设置cookie名称,来对cookie进行替换
        // 同时 将过期时间expires设置为过去的时间,
        unset: function(name, path, domain, secure) {
          this.set(name, '', new Date(0), path, domain, secure);
        }
      }
    

    浏览器本地存储中 cookie 和 localStorage 有什么区别? localStorage 如何存储删除数据。

    sessionStorage、localStorage和cookie 这三者都是用于浏览器端存储数据,而且都是字符串类型的键值对

    区别在于:

    • 数据传输方面:在每个http请求中都会附加cookie信息,cookie中的信息能够被推送到服务器端;而sessionStorage和localStorage不会被推送到服务器端
    • 存储大小不同:cookie最大支持4KB,而sessionStorage和localStorage一般在2.5~10MB
    • 生命周期:默认情况下,cookie开始于浏览器启动,结束于浏览器关闭,但是可以手动设置cookie的过期时间,同时,到期后被删除;而对于localStorage,没有过期时间,原则上只要不手动删除,其会一直被保存在本地上,sessionStorage的数据关闭浏览器时清除
    • 被创造的初衷不同:sessionStorage和localStorage都属于WebStorage,创建他们的目的就是用于存储客户端数据;
      而cookie最早在网景的浏览器中被支持,主要目的是为了辨别用户身份而存储在本地终端的数据。

    参考:在HTML5的时代,重新认识Cookie


    参考:


    相关文章

      网友评论

        本文标题:简述cookie 、localStorage和sessionSt

        本文链接:https://www.haomeiwen.com/subject/ahhzkxtx.html