• 这一次带你彻底了解前端本地存储


    随着Web应用程序的出现,直接在客户端存储用户信息的需求也随之出现。那么我们前端常用的存储方式有哪些呢?

    前言

    如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,文章公众号首发,关注 前端南玖 第一时间获取最新的文章~

    HTML5常用的几种存储方式

    • 本地存储:localStorage, sessionStorage, cookies
    • 离线缓存:application cache
    • 前端数据库:indexedDB, webSQL

    HTTP cookie 通常也叫做cookie,最初用于在客户端存储会话信息。cookie是与特定域名绑定的,设置cookie后,它会与请求一起发送到创建它的域。 这个限制能保证cookie中存储的信息只对被认可的接收者开放,不被其它域访问。

    cookie的构成

    • 名称: 唯一标识cookie的名称。cookie不区分大小写,cookie名必须经过URL编码。
    • 值: 存储在cookie里的字符串值,这个值必须经过URL编码。
    • 域: cookie的有效域,发送到这个域的所有请求都会包含对应的cookie。
    • 路径: 请求URL中包含这个路径才会把cookie发送到服务器。
    • 过期时间: 表示何时删除cookie的时间戳。(即什么时间之后就不会发送到服务器了)
    • 安全标识: 设置之后,只在使用SSL安全连接的情况下才会把cookie发送到服务器。

    限制

    因为cookie存储在客户端机器上,所以为保证它不会被恶意利用,浏览器会施加限制。

    • 不超过300个cookie
    • 每个cookie不超过4096字节(4kb)
    • 每个域不超过20个cookie
    • 每个域不超过81920字节

    JavaScript中的cookie

    在JavaScript中处理cookie比较麻烦,因为接口过于简单,只有BOMdocument.cookie属性。

    获取cookie

    document.cookie返回包含页面中所有有效cookie的字符串,以分号分隔;

    name1=value1;name2=valve2;name3=value3
    

    所有名和值都是URL编码,因此必须使用decodeURIComponent()解码

    设置cookie

    name=value; expires=expiration_time; path=domain_path; domain=domain_namel secure
    //在所有这些参数中,只有cookie的名称和值是必须的
    
    document.cookie = `${encodeURIComponent('name')}=${encodeURIComponent('nanjiu')};domain=bettersong.github.io;`
    
    

    删除cookie

    没有直接删除已有cookie的方法,但可以通过设置其过期时间来达到删除效果;

    document.cookie = 'uid=dkfywqkrhkwehf23;expires=' + new Date(0) + ';path=/;secure;
    

    cookie是如何工作的?

    request:

    当浏览器发起一个请求时,浏览器会自动检查是否有相应的cookie,如果有则将cookie添加到Request HeadersCookie字段中

    response:

    当服务器需要cookie时,在http请求的Response Headers字段中添加Set-Cookie字段,浏览器接收到之后会自动解析识别,将cookie种下。

    localStorage 和sessionStorage

    localStorage只要在相同的协议,域名,端口下就能读取或修改同一份localStorage数据,sessionStorage对象只存储会话数据,这意味着数据只会存储到浏览器关闭。sessionStorage除了协议,域名,端口外,还要求在同一窗口下。

    • localStorage 永久存储,除非手动删除。
    • sessionStorage存储到浏览期关闭就消失了
    • 每个域名给localStorage和sessionStorage分配的存储空间时5M ,cookie是4kb

    方法

    setItem('key','value')  // 存储数据
    
    getItem('key')	// 读取数据
    
    remove('key')	// 删除数据
    
    clear()	// 清空
    

    **⚠️注意:Storage类型智能存储字符串。非字符串数据在存储之前会自动转换为字符串,并且这种转换不能在获取数据时撤销,也就是说你在获取storage数据时,拿到的一定是字符串,需要自己手动转 **

    存储JSON对象的数据

    Storage是以字符串保存数据的,所以在保存JSON格式的数据之前,最好把数据转化为字符串,这个操作叫序列化

    let obj = {
      name: '南玖',
      age: 18
    }
    localStorage.setItem('author',JSON.stringify(obj))
    
    const author = JSON.parse(localStorage.getItem('author'))
    

    localStorage与sessionStorage的异同

    相同点: 两者的API完全相同,都是在浏览器端存储数据,存储大小都是5M

    不同点:

    1. localStorage存储的数据是永久性数据,页面刷新,即使浏览器重启,甚至操作系统重启也不会丢失,并且存储的数据在同源(协议、域名、端口号一致)下的标签页和window窗口之间共享。
    2. sessionStorage存储的数据有些苛刻,页面刷新仍然有效,选项卡关闭时数据丢失。但是在相同标签页打开的多个iframe之间数据可以共享(同源的情况下)。

    存储事件

    每当Storage对象发生变化时,都会触发storage事件。(增删改查)

    这个事件的时间对象有4个属性:

    • domain:存储变化对应的域
    • key:被设置或被删除的键
    • newValue:键被设置的新值,若被删除则为null
    • oldValue:键变化之前的值
    window.addEventListener('storage', e=>{
        console.log(e.domain)
    })
    

    对于sessionStoragelocalStorage上的任何更改都会触发storage事件,但storage事件不会区分这两者

    IndexedDB

    Indexed Database API简称 IndexedDB,是浏览器中存储结构话数据的一个方案。IndexedDB用于代替目前已废弃的 Web SQL

    基本概念

    • Database:通过open方法直接打开
    const db = indexDB.open('testDB');
    
    • Object store:这个就是DB里面具体存储的对象。这个可对应SQL里面的table内容。其存储的结构为:

    • Index:有点类似于外链,它本身是一种Object store,主要用来本体的store中,索引另外的object store里面的数据。
    // 创建 index
    var myIndex = objectStore.index('lName'); 
    
    • transaction: 事务其实就是一系列 CRUD 的集合内容。如果其中一个环节失败了,那么整个事务的处理都会被取消。
    • cursor: 主要是用来遍历 DB 里面的数据内容。主要是通过 openCursor 来进行控制。

    创建数据库

    const request = indexedDB.open(dbName);
    
    request.onerror = function(event) {
      // 错误处理程序。
    };
    request.onupgradeneeded = function(event) {
      var db = event.target.result;
      // 设置 id 为 primaryKey 参数
      var objectStore = db.createObjectStore("customers", { keyPath: "id",{autoIncrement:true} });
      
      // 设置指定索引,并确保唯一性
      objectStore.createIndex("name", "name", { unique: false });
      objectStore.createIndex("email", "email", { unique: true });
    
    };
    

    创建 Object Store

    使用的方法就是 IDBDatabase 上的 createObjectStore 方法。

    const objectStore = db.createObjectStore("customers", { keyPath: "id",{autoIncrement:true} });
    
    • keyPath: 用来设置主键的 key,具体区别可以参考下面的 keyPath 和 generator 的区别。
    • autoIncrement: 是否使用自增 key 的特性。

    创建的 key 主要是为了保证,在数据插入时唯一性的标识。

    设置索引 index

    在完成 PK(Primary key) 创建完毕后,为了更好的搜索性能我们还需要额外创建 index。这里可以直接使用:

    objectStore.createIndex('indexName', 'property', options);
    
    • indexName: 设置当前 index 的名字
    • property: 从存储数据中,指明 index 所指的属性。

    其中,options 有三个选项:

    • unique: 当前 key 是否能重复 (最常用)
    • multiEntry: 设置当前的 property 为数组时,会给数组里面每个元素都设置一个 index 值。
    // 创建一个名字叫 titleIndex 的 index,并且存储的 index 不能重复
    DB.createIndex('titleIndex', 'title', {unique: false});
    

    增删数据

    在 IndexedDB 里面进行数据的增删,都需要在 transaction 中完成。而这个增删数据,大家可以理解为一次 request,相当于在一个 transaction 里面管理所有当前逻辑操作的 request。所以,在正式开始进行数据操作之前,还需要给大家简单介绍一些如果创建一个事务。

    事务的创建

    transaction API,在创建时,你需要手动指定当前 transaction 是那种类型的操作,基本的内容有:

    • "readonly":只读
    • "readwrite":读写
    • "versionchange":这个不能手动指定,会在 upgradeneeded 回调事件里面自动创建。它可以用来修改现有 object store 的结构数据,比如 index 等。

    你可以通过在数据库打开之后,通过 IDBDataBase 上的 transaction 方法创建

    const transaction = db.transaction(["customers"], "readwrite");
    const objectStore = transaction.objectStore("customers");
     // 遍历存储数据
    for (let i in customerData) {
      const request = objectStore.add(customerData[i]);
      request.onsuccess = function(event) {
        // success, done?
      };
    }
    

    操作数据

    完成了事务的创建之后,我们就可以正式的开始进行数据的交互操作了,也就是写我们具体的业务逻辑。如下,一个完整数据事务的操作。

    const tx = db.transaction("books", "readwrite");
    const store = tx.objectStore("books");
    
    store.put({title: "aaaaa", author: "Fred", isbn: 1111});
    store.put({title: "bbbbb", author: "Fred", isbn: 2222});
    store.put({title: "ccccc", author: "Barney", isbn: 3333});
    
    tx.oncomplete = function() {
      // All requests have succeeded and the transaction has committed.
    };
    

    索引数据

    索引数据是所有数据库里面最重要的一个。这里,我们可以使用index 来做。例如,通过 index 来快速索引 key 值

    const index = objectStore.index("username");
    index.openCursor.onsuccess = function(event) {
      // 处理成功
    };
    

    点赞、收藏和评论

    我是前端南玖,感谢各位的:点赞、收藏和评论,我们下期见!

    加入前端交流群928029210,我们一起学习~

    作者:前端南玖

    -------------------------------------------

    个性签名:智者创造机会,强者把握机会,弱者坐等机会。做一个灵魂有趣的人!

    如果觉得这篇文章对你有小小的帮助的话,可以关注下方公众号,在该公众号同样会推送技术文章给大家,谢谢~

    欢迎加入前端技术交流群:928029210

    逐梦wx
  • 相关阅读:
    jfreeChart柱状图各属性详细设置
    eclipse 常用快捷键及调试方法
    Java利用Preferences设置个人偏好
    图说设计模式(UML和设计模式)
    JFreeChart 使用一 饼图之高级特性
    使用批处理创建永久生效的环境变量
    tnsnames.ora 监听配置文件详解
    oracle本机登录不上dba的权限不足错误
    Oracle自动备份脚本(网上找到的资料)
    初探Docker
  • 原文地址:https://www.cnblogs.com/songyao666/p/15492313.html
Copyright © 2020-2023  润新知