localStorage、sessionStorage、IndexedDB、Cookies浏览器数据存储方案一览

localStorage、sessionStorage、IndexedDB、Cookies浏览器数据存储方案一览

一、localStorage

  localStorage是一种在客户端浏览器本地化存储的机制,属性为只读,是绝大多数浏览器原生支持的属性,允许在浏览器中存储键值对数据。

  (1)localStorage的使用

if(window.localStorage) { 
    // 保存数据 
    localStorage.setItem("score", 100) 
    // 读取数据 
    let score = localStorage.getItem("score") 
    console.log("score") 
    // 删除数据 
    localStorage.removeItem("score") 
    // 删除所有保存的数据   
    localStorage.clear()
} else { 
    console.log("浏览器不支持localStorage") 
}

 

打印出来的结果:

  注意此时打印出的数据为string类型,这是因为localStorage只支持string类型的储存,它将存进去的int型数据转换成了string类型。

  (2)localStorage的优势

  localStorage仅在本地保存数据,不会将自动数据发送给服务器,因此可适当节省网络流量。localStorage的储存容量在2. 5MB到10MB之间,远超过cookie的最大储存容量4KB,localStorage能够持久化储存,即使窗口或者浏览器关闭也能一直保存数据,除非主动清除其中的数据。localStorage的数据在所有同源窗口中都是共享的,即在同一个域名同一个端口和同一种协议下可以实现数据的共享。localStorage由浏览器原生支持,具有容量大和容易使用的特点。

  (3)localStorage的缺陷

  localStorage本质上是对字符串的读取,如果储存内容过多会消耗内存空间而导致页面变卡。而由于其储存的数据持久有效且容易读取,所以它的安全性也比较差,不适宜用来保存用户敏感信息。

二、sessionStorage

  同localStorage一样,sessionStorage也是一种在客户端浏览器本地化储存的机制,也能在浏览器中储存键值对数据,主要的区别就是sessionStorage中的数据是临时保存的,用于本地储存一个回会话(session)中的数据,这些数据只有在同一个会话中的页面中才能访问,会话结束之后便随之销毁。

  (1)sessionStorage的使用

   sessionStorage与localStorage的主要区别是储存数据生命周期的问题,因此调用语法也是相同的。

if(window.sessionStorage) { 
    // 保存数据 
    sessionStorage.setItem("score", 100) 
    // 读取数据 
    let score = sessionStorage.getItem("score") 
    console.log("score") 
    // 删除数据 
    sessionStorage.removeItem("score") 
    // 删除所有保存的数据   
    sessionStorage.clear()
} else { 
    console.log("浏览器不支持sessionStorage") 
}

  (2)sessionStorage的优缺陷

  sessionStorage作为一种会话级别的储存,仅在当前会话周期内有效,因此适合作为会话周期内事件及页面全局通信的临时性使用的数据储存方式,不能够储存长期使用的静态资源数据。

三、IndexedDB

  前面提到的两种数据储存方式,它们的储存量都在10MB以内,虽然远远大于cookie的4KB储存空间,但是任然不适合作为客户端大量储存数据的方式。因此,适用于客户端储存大容量数据的浏览器数据库IndexedDB应运而生。简单地说,IndexedDB作为一种本地数据库,具有以下几个特点:

  一、异步操作。与前面提到的两种数据储存方式不同,IndexedDB支持数据读写时的异步操作,而不是同步语句。localStorage和sessionStorage主要应用于少量数据的读取,因此进行同步操作对用户的延迟感受不那么明显,但是IndexedDB通常涉及大量数据的读写操作,而同步的设计会拖慢网页,锁死浏览器,造成卡顿,而异步设计使得用户可以进行其他操作,使用体验更好。

  二、储存空间大。IndexedDB可储存数百MB以上的数据量(250MB以上)。

  三、键值对储存。同前述两种储存方式一样,IndexedDB也是采用键值对的储存方式,主键具有唯一性,同样使用JSON格式储存数据,且除字符串外还可以储存二进制数据。

  四、同源限制。正如大多数的 web 储存解决方案一样,IndexedDB 也遵守同源策略。因此当你在某个域名下操作储存数据的时候,你不能操作其他域名下的数据。

  (1)IndexedDB的使用

  通过IndexedDB.open()打开或创建一个新的数据库,并指定一个版本(新建版本默认为1),该方法返回的对象对应三种操作结果

const request = window.indexedDB.open("transcript", 1)

request.onerror = function (event) {
  console.log("数据库打开报错");
};

var db;
request.onsuccess = function (event) {
  db = request.result;
  console.log("数据库打开成功");
};

request.onupgradeneeded = function (event) {
  db = event.target.result;
  console.log("指定的版本号,大于数据库的实际版本号,数据库升级");
}

  如果打开时指定数据库不存在就会新建,新建后触发upgradeneeded事件,并在onupgradeneeded监听事件中完成后续操作。
  

request.onupgradeneeded = function(event) {
  db = event.target.result;

  // 新建一张名为person,主键为id的表格
  var objectStore;
  if (!db.objectStoreNames.contains("person")) {
    // 如果不存在则新建
    objectStore = db.createObjectStore("person", { keyPath: "id" });
  }
}    

  主键相当于属性,主键是数据库表中的唯一性索引且只能有一个主键,新建表后可以新建索引,索引可以帮助查找数据。

objectStore.createIndex("name", "name", { unique: true })
objectStore.createIndex("grade", "grade", { unique: true })

  IDBObject.createIndex()的三个参数分别为索引名称、索引所在的属性、配置对象(说明该属性是否包含重复的值)。

  IndexedDB有一个事务对象,在事务中可以为对象仓库添加数据和读取数据。新建事务后通过事务的objectStore(name)方法,获取对象仓库,对象仓库通过add()方法向其中写入数据记录。

function recordGrades() {
  var request = db.transaction(["person"], "readwrite")
    .objectStore("person")
    .add({ id: 1, name: "张三", grade: 100});

  request.onsuccess = function (event) {
    console.log("成绩录入成功");
  };

  request.onerror = function (event) {
    console.log("成绩录入失败");
  }
}

recordGrades();

   写入数据是一个异步的过程,它有success和error两个返回状态,可以在这两个状态中设计相应的回调函数。读取数据时也是通过事务transaction对象,只需要传入表格的名称,然后通过get()方法读取数据。此外,通过delete()方法可以删除数据记录,当用createIndex()创建了索引时,可以用对象仓库的index()属性获取索引名称,从索引名称中检索获取指定的数据记录。

  

var transaction = db.trancaction(["person"])
// 通过事务transaction对象
var personStore = transaction.objectStore("person")
var getData = personStore.get(1)

getData .onsuccess = function(event) {
  console.log("Grade for" + getData.result.name + "is" + getData .result.grade)
}

const grades = [
  {id: 2, name: "李四", grade: 96},
  {id: 3, name: "王五", grade: 97}
]
const request = window.indexedDB.open("transcript", 2)

request.onupgradeneeded = function (event) {
    db = event.target.result
     // 新建一张名为person,主键为id的表格
    var objectStore
    if (!db.objectStoreNames.contains("person")) {
        // 如果不存在则新建
        objectStore = db.createObjectStore("person", { keyPath: "id"         })
    objectStore.createIndex("name", "name", { unique: false })
    objectStore.createIndex("grade", "grade", { unique: true })

    objectStore.transaction.oncomplete = function (event) {
    var request1 = db.transaction(["person"],   "readwrite").objectStore("person").add({ id: 1, name: "张三", grade: 100 })
    var transcriptName = db.transaction(["person"], "readwrite").objectStore("person")
    // add()添加数据
    grades.forEach((item) => {
        transcriptName.add(item)
    }
    // delete()删除数据
    var delRequest = db.transaction(["person"], "readwrite").objectStore("person").delete("1")
    delRequest.onsuccess = function(event) {       
        console.log("数据已删除")     
    }

    // openCursor()遍历数据
    var cursorStore = db.transaction("person").objectStore("person")
    cursorStore.openCursor().onsuccess = function (event) {
        var cursor = event.target.result;

        if (cursor) {
            console.log("Id: " + cursor.key)
            console.log("Name: " + cursor.value.name)
            console.log("Grade: " + cursor.value.grade)
            cursor.continue();
      } else {
        console.log("没有更多数据了!")
      }
  }
        // put()更新数据
        var putRequest = db.transaction(["person"], "readwrite").objectStore("person").put({ id: 1, name: "张大三", grade: 99 });
        putRequest.onsuccess = function (event) {
            console.log("数据更新成功")
        }

        putRequest.onerror = function (event) {
            console.log("数据更新失败")
        }
   // index()获取索引
        var index = objectStore.index("name")
        index.get("张三").onsuccess = function(event) {
            console.log("张三的成绩是 " + event.target.result.grade);
        }
    }
}

                        

   

  (2)常用接口

  IndexedDB的一些常用接口为触发事件操作数据的存储和修改提供便利。

  IDBDataBase 表示一个数据库连接。这是在数据库中获取事务的唯一方式。

  IDBObjectStore 表示允许访问通过主键查找的 IndexedDB 数据库中的一组数据的对象存储区。

  IDBIndex  使用索引来检索 IndexedDB 数据库中的数据子集。

  IDBTransaction 在数据库上创建一个事务,指定作用域(例如要访问的存储对象),并确定所需的访问类型(只读或读写)。

  IDBRequest 处理数据库请求并提供对结果访问的通用接口。

  IDBCursor  用于遍历objectStore对象的数据。

  IDBKeyRange 定义可用于从特定范围内的数据库检索数据的键范围。

四、Cookies

   Cookies就是一些数据,存储在客户端的文本文件中,供服务端识别客户端用户信息。通常情况下,如果没有主动给Cookie设置一个过期时间,浏览器关闭时,Cookie即删除。我们可以使用document.cookie来执行对cookie的增删改即读取操作,他们分别对应的方法如下:

  创建Cookie:

document.cookie = "isLogin = true"

  添加过期时间:

document.cookie="iSLogin=true; expires=Sun Jul 20 2021 17:17:55 GMT+0800"

  读取Cookie:

var status = document.cookie

  将一个已有Cookie值按创建方式重新赋值即可完成修改:

document.cookie = "isLogin = false"

  将Cookie的过期时间修改为以前的时间即可完成删除操作:

document.cookie="iSLogin=true; expires=Mon Jul 19 2021 17:17:55 GMT+0800"

  Cookie的储量较小,基本在4KB以内,会跟随请求一起发送给服务器。

  参考:

    浏览器数据库 IndexedDB 入门教程

 

  

 

原文链接:https://www.cnblogs.com/leayun/archive/2021/07/24/15055624.html