最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 一文搞懂Cookie、Storage、IndexedDB

    正文概述 掘金(执鸢者)   2021-02-28   779

    一、Cookie

    1.1 定义

    1.2 Cookie组成

    一文搞懂Cookie、Storage、IndexedDB

    1. NAME=VALUE

    Cookie的名称和值,其中NAME是唯一标识cookie的名称,不区分大小写;VALUE是存储在Cookie里的字符串值,该值必须经过URL编码。

    1. Domain=域名

    Cookie有效的域,发送到这个域的所有请求都会包含对应的Cookie。(若不指定则默认为创建Cookie的服务器的域名)

    1. Path=PATH

    请求URL中包含这个路径才会把Cookie发送到服务器(若不指定则默认为文档所在的文件目录)

    1. Expires=DATE

    Cookie的有效期,默认情况下,浏览器会话结束后会删除所有cookie。

    1. Secure

    设置后仅在HTTPS安全通信时才会发送Cookie

    1. HttpOnly

    设置后只能在服务器上读取,不能再通过JavaScript读取Cookie

    const express = require('express');
    
    const app = express();
    
    app.get('/', (req, res) => {
        res.cookie('myCookie', 'myCookie', {
            expires: new Date(Date.now() + 900000),
            secure: true,
            httpOnly: true
        });
        res.send('get请求已经被处理');
    })
    app.listen(8090, () => {
        console.log('8090端口已经启动!!!');
    });
    
    1. 第一次返回的Cookie结果

    一文搞懂Cookie、Storage、IndexedDB 2. 后续请求所带的Cookie信息 一文搞懂Cookie、Storage、IndexedDB

    1.3 Cookie特点

    1. 每个Cookie不超过4096字节;
    2. 每个域中Cookie个数有限制,就拿最新版来说:IE和Edge不超过50个;Firefox不超过150个;Opera不超过180个;Safari和Chrome没有限制;
    3. Cookie超过单个域的上限,浏览器会删除之前设置的Cookie;
    4. 创建的Cookie超过最大限制,该Cookie会被静默删除;
    5. 可设置失效时间,没有设置则会话结束会删除Cookie;
    6. 每个请求均会携带Cookie,若Cookie过来会带来性能问题;
    7. 受同源策略限制

    1.4 Cookie的操作

    class CookieUtil {
        // 获取Cookie中的对应属性
        static get(name) {
            const cookies = document.cookie;
            const cookiesArr = cookies.split(';');
            for (let index = 0; index < cookiesArr.length; index++) {
                const presentCookieArr = cookiesArr[index].split('=');
                if (presentCookieArr[0] === name) {
                    return presentCookieArr[1];
                }
            }
    
            return null;
        }
    
        // 设置对应的Cookie值
        static set(name, value, expires, path, domain, secure) {
            let cookieText = `${name}=${value}`;
            if (expires instanceof Date) {
                cookieText += `; expire=${expires.toGMTString()}`;
            }
            if (path) {
                cookieText += `; path=${path}`;
            }
            if (domain) {
                cookieText += `; domain=${domain}`;
            }
            if (secure) {
                cookieText += `; secure`;
            }
            document.cookie = cookieText;
        }
    
        // 删除对应的Cookie
        static deleteCookie(name) {
            CookieUtil.set(name, '', new Date(0));
        }
    }
    

    二、Web Storage

    2.1 sessionStorage

    1. sessionStorage对象值存储会话数据,其生命周期会存储到浏览器关闭。(在该过程中刷新页面其数据不受影响)
    2. 浏览器在实现存储写入时使用同步阻塞方式,数据会被立即提交到存储。
    3. 独立打开同一个窗口同一个页面或一个Tab,sessionStorage也是不一样的。
    4. 存储空间大小限制为每个源不超过5M。
    // 使用方法存储数据
    sessionStorage.setItem('sessionName1', 'value1');
    // 使用属性存储数据
    sessionStorage.sessionName2 = 'value2';
    
    // 使用方法取得数据
    const sessionValue1 = sessionStorage.getItem('sessionName1');
    console.log('sessionValue1的值为:', sessionValue1);
    // 使用属性取得数据
    const sessionValue2 = sessionStorage.sessionName2;
    console.log('sessionValue2的值为:', sessionValue2);
    
    // 循环遍历sessionStarage
    for (let index = 0; index < sessionStorage.length; index++) {
        // 使用key()方法获得指定索引处的名称
        const key = sessionStorage.key(index);
        const value = sessionStorage.getItem(key);
        console.log('循环遍历结果:', key, value);
    }
    
    // 使用方法删除值
    sessionStorage.removeItem('sessionName1');
    // 使用delete删除值
    delete sessionStorage.sessionName2;
    
    // 使用clear()方法清空sessionStorage
    sessionStorage.clear();
    

    2.2 localStorage

    1. 生命周期是永久的,除非被清除,否则永久保存。
    2. 存储空间大小限制为每个源不超过5M。
    3. 受同源策略限制。
    4. 浏览器存储时采用同步存储方式。
    // 使用方法存储数据
    localStorage.setItem('localName1', 'value1');
    // 使用属性存储数据
    localStorage.localName2 = 'value2';
    
    // 使用方法取得数据
    const localValue1 = localStorage.getItem('localName1');
    console.log('localValue1的值为:', localValue1);
    // 使用属性取得数据
    const localValue2 = localStorage.localName2;
    console.log('localValue2的值为:', localValue2);
    
    // 循环遍历localStarage
    for (let index = 0; index < localStorage.length; index++) {
        // 使用key()方法获得指定索引处的名称
        const key = localStorage.key(index);
        const value = localStorage.getItem(key);
        console.log('循环遍历结果:', key, value);
    }
    
    // 使用方法删除值
    localStorage.removeItem('localName1');
    // 使用delete删除值
    delete localStorage.localName2;
    
    // 使用clear()方法清空localStorage
    localStorage.clear();
    

    三、IndexedDB

    3.1 IndexedDB整个结构

    一文搞懂Cookie、Storage、IndexedDB 对于整个IndexedDB为上述图中所示:

    1. 一个域名下可以包含多个数据库;
    2. 一个数据库中包含多个对象仓库,就类似与Mysql一个库中有多张表一样。
    3. 每个对象仓库中包含多条数据记录。

    3.2 主要特点

    1. 键值对存储

    在对象仓库中,数据以“键值对”形式保存,每个数据记录都有独一无二的主键。

    1. 异步

    IndexedDB操作时不会锁死浏览器,用户依然可以进行其它操作。

    1. 支持事务

    一些列操作步骤之中只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。

    1. 受同源策略限制

    只能访问自身域名下的数据库,不能跨域访问数据库。

    1. 存储空间大

    每个源都有存储空间的限制,而且这个限制跟浏览器有关,例如Firefox限制每个源50MB,Chrome为5MB。

    1. 支持二进制存储

    不仅可以存储字符串,还可以存储二进制数据(ArrayBuffer和Blob)

    3.3 数据库操作

    3.3.1 初始化数据库

    class IndexedDBOperation {
      constructor(databaseName, version) {
          this.atabaseName = databaseName;
          this.version = version;
          this.request = null;
          this.db = null;
      }
    
      // 数据库初始化操作
      init() {
          this.request = window.indexedDB.open(this.databaseName, this.version);
          return new Promise((resolve, reject) => {
              this.request.onsuccess = event => {
                  this.db = event.target.result;
                  console.log('数据库打开成功');
                  resolve('success');
              };
              this.request.onerror = event => {
                  console.log('数据库打开报错');
                  reject('error');
              };
              this.request.onupgradeneeded = event =>{
                  this.db = event.target.result;
                  console.log('数据库升级');
                  resolve('upgradeneeded');
              };
          });
      }
    }
    

    3.3.2 对象仓库操作

    class IndexedDBOperation {
      // ……
      // 创建数据仓库
      createObjectStore(objectStoreName, options) {
          let objectStore = null;
          if (!this.db.objectStoreNames.contains(objectStoreName)) {
              objectStore = this.db.createObjectStore(objectStoreName, options);
          }
          return objectStore;
      }
    }
    

    3.3.3 数据操作

    class IndexedDBOperation {
      // ……
      // 新增内容
      add(objectStore, content) {
          objectStore.add(content);
      }
      
      // 获取内容
      get(objectStore, id) {
          const request = objectStore.get(id);
          return new Promise((resolve, reject) => {
              request.onsuccess = resolve;
              request.onerror = reject;
          });
      }
      
      // 更新内容
      update(objectStore, content) {
          const request = objectStore.put(content);
          request.onsuccess = event => {
              console.log('更新成功');
          };
          request.onerror = event => {
              console.log('更新失败');
          };
      }
      
      // 删除内容
      remove(objectStore, deleteId) {
          const request = objectStore.delete(deleteId);
          request.onsuccess = event => {
              console.log('删除成功');
          };
          request.onerror = event => {
              console.log('删除失败');
          };
      }
    }
    

    3.3.4 遍历内容

    class IndexedDBOperation {
      // ……
      // 打印全部数据
      printAllDataByCursor(objectStore) {
          const cursorRequest = objectStore.openCursor();
          cursorRequest.onsuccess = event => {
              const cursor = event.target.result;
              if (cursor) {
                  console.log(`利用游标打印的内容,id为${cursor.key}, 值为${cursor.value}`);
                  // 移动到下一条记录
                  cursor.continue();
              }
          };
      }
    }
    

    3.3.5 调用代码

    const indexedDBOperation = new IndexedDBOperation('dbName1', 1);
    indexedDBOperation
    .init()
    .then(type => {
        const objectStoreName = 'testObjectStore';
        if (type === 'upgradeneeded') {
            indexedDBOperation.createObjectStore(objectStoreName, {
                keyPath: 'id'
            });
        }
        const transaction = indexedDBOperation.db.transaction([objectStoreName], 'readwrite');
        const objectStore = transaction.objectStore(objectStoreName);
    
        indexedDBOperation
        .get(objectStore, 1)
        .then(event => {
            if (event.target.result) {
                indexedDBOperation.update(objectStore, {
                    id: 1,
                    name: '执鸢者+纸鸢'
                });
                console.log('数据库中已经存在', event.target.result, ',则进行更新操作');
            }
            else {
                indexedDBOperation.add(objectStore, {
                    id: 1,
                    name: '执鸢者'
                });
                console.log('数据库中不存在,则进行添加');
            }
        })
        .catch(console.log);
    
        indexedDBOperation.printAllDataByCursor(objectStore);
    
        transaction.onsuccess = event => {
            console.log('事务操作成功');
        };
        transaction.onerror = event => {
            console.log('事务操作失败');
        };
        transaction.oncomplete = event => {
            console.log('整个事务成功完成');
        }
    })
    .catch(console.log);
    

    参考文献

    1. 浏览器数据库 IndexedDB 入门教程
    2. javascript高级程序设计4
    3. IndexedDB API

    1.如果觉得这篇文章还不错,来个分享、点赞吧,让更多的人也看到

    2.关注公众号执鸢者,领取学习资料(前端“多兵种”资料),定期为你推送原创深度好文


    起源地下载网 » 一文搞懂Cookie、Storage、IndexedDB

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元