灏天阁

本地存储

· Yin灏

本地存储简介

在 HTML4.01 中,想要在浏览器端存储用户的某些数据时,我们一般只能使用 Cookie 来实现。不过 Cookie 这种方式有很多限制因素,如下所示。

  • 大小限制:大多数浏览器支持最大为 4KB 的 Cookie。
  • 数量限制:大多数浏览器只允许每个站点存储 20 个 Cookie,如果想要存储更多 Cookie,则旧的 Cookie 将会被丢弃。
  • 有些浏览器还会对它们将接收的来自所有站点的 Cookie 总数做出绝对限制,通常为 300 个。
  • Cookie 默认情况下都会随着HTTP请求发送到后台,但是实际上大多数请求都是不需要 Cookie 的。

为了解决 Cookie 这种方式的限制,HTML5新增了3种全新的数据存储方式:localStorage、sessionStorage 和 indexedDB。其中,localStorage 用于永久保存客户端的少量数据,sessionStorage 用于临时保存客户端的少量数据,而 indexedDB 用于永久保存客户端的大量数据。

localStorage

在 HTML5 中,我们可以使用 localStorage 对象来 “永久” 保存客户端的少量数据。即使浏览器被关闭了,使用 localStorage 对象保存的数据也不会丢失,下次打开浏览器访问网站时仍然可以继续使用。

对于 localStorage 来说,每一个域名可以保存 5MB 数据,现在绝大多数浏览器都已经支持 localStorage。localStorage 对象的常用方法有5种,

举例:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      window.onload = function () {
        var oUser = document.getElementById("user");
        var oPwd = document.getElementById("pwd");
        var oBtn = document.getElementById("btn");
        var oMes = document.getElementById("mes");
        //页面一打开时,使用getItem()方法获取数据
        oMes.innerHTML =
          "账号:" +
          localStorage.getItem("user") +
          "<br/>密码:" +
          localStorage.getItem("pwd");
        //点击按钮后,使用setItem()方法设置数据
        oBtn.onclick = function () {
          localStorage.setItem("user", oUser.value);
          localStorage.setItem("pwd", oPwd.value);
          oMes.innerHTML = "账号:" + oUser.value + "<br/>密码:" + oPwd.value;
        };
      };
    </script>
  </head>
  <body>
    账号:<input id="user" type="text" /><br />
    密码:<input id="pwd" type="text" />
    <input id="btn" type="button" value="设置" />
    <p id="mes" style="color: red"></p>
  </body>
</html>

分析:

在页面一打开时,我们就使用 getItem() 方法来获取数据,由于键名为 “user” 和键名为 “pwd” 的这两个 key 没有值,因此都为 null。

当在文本框中输入内容,然后点击【设置】按钮后,我们使用 setItem() 方法设置数据,此时可以看到预览效果:

当我们把浏览器关闭,然后重新打开时,神奇的一幕就出现了:数据竟然保存下来了

此时打开浏览器控制台也可以查看 localStorage 保存下来的数据

如果仅仅使用 DOM 操作,当关闭浏览器然后重新打开时,数据是不会保存下来的。使用 localStorage 对象保存下来的数据是永久性的,其中数据是保存在用户自己的电脑中,而不是保存在服务器中。

举例:留言板

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      window.onload = function () {
        var oList = document.getElementById("list");
        var oTxt = document.getElementById("txt");
        var oBtn = document.getElementById("btn");
        var oBtnClear = document.getElementById("btnClear");
        oBtn.onclick = function () {
          //生成随机4位数,作为key
          var strKey = "";
          for (var i = 0; i < 4; i++) {
            strKey += Math.floor(Math.random() * (9 + 1));
          }
          //获取文本框的值,作为value
          var strValue = oTxt.value;
          //调用setItem()设置数据
          localStorage.setItem(strKey, strValue);
          //插入数据到ul中
          var oLi = document.createElement("li");
          var oLiTxt = document.createTextNode(strKey + ":" + strValue);
          oLi.appendChild(oLiTxt);
          oList.appendChild(oLi);
        };
        oBtnClear.onclick = function () {
          localStorage.clear();
          oList.innerHTML = "";
        };
        //页面载入时,读取数据并添加到页面中
        for (var i = 0; i < localStorage.length; i++) {
          var strKey = localStorage.key(i);
          var strValue = localStorage.getItem(strKey);
          var oLi = document.createElement("li");
          var oLiTxt = document.createTextNode(strKey + ":" + strValue);
          oLi.appendChild(oLiTxt);
          oList.appendChild(oLi);
        }
      };
    </script>
  </head>
  <body>
    <ul id="list"></ul>
    <textarea id="txt" cols="30" rows="10"></textarea><br />
    <input id="btn" type="button" value="发表" />
    <input id="btnClear" type="button" value="清空" />
  </body>
</html>

分析:

我们使用 localStorage 对象配合 DOM 操作制作了一个简易留言板。当我们点击【发表】按钮后,会添加一个列表项到页面中,并且使用 setItem() 方法记录数据。当我们点击【清空】按钮后,会清空页面的列表项,并且使用 localStorage.clear() 清空所有数据。

//生成随机4位数,作为key
var strKey = "";
for(var i=0;i<4;i++){
  strKey += Math.floor(Math.random() * (9 + 1));
}

上面这段代码用于生成随机 4 位数,然后作为 key。Math.floor(Math.random()*(m+1)) 用于生成 0~m 之间的随机整数。

//页面载入时,读取数据并添加到页面中
for(var i = 0; i < localStorage.length; i++) {
  var strKey = localStorage.key(i);
  var strValue = localStorage.getItem(strKey);
  var oLi = document.createElement("li");
  var oLiTxt = document.createTextNode(strKey + ":" + strValue);
  oLi.appendChild(oLiTxt);
  oList.appendChild(oLi);
}

上面这段代码用于在页面载入时,读取数据并且添加到页面中去。for 循环结合 localStorage.key() 方法来实现 localStorage 的遍历,这种方式在实际开发中用得非常多。

sessionStorage

在 HTML5 中,我们可以使用 sessionStorage 对象来 “暂时” 保存客户端的少量数据。sessionStorage 对象跟 localStorage 对象非常相似,两者有着完全相同的方法

不过,sessionStorage 对象跟 localStorage 对象也有本质上的区别:sessionStorage 对象保存的是“临时数据”,用户关闭浏览器后,数据就会丢失;而 localStorage 对象保存的是“永久数据”,用户关闭浏览器后,数据依然存在。

此外,localStorage 和 sessionStorage 都是 window 对象下的子对象。也就是说,localStorage.getItem() 其实是 window.localStorage.getItem() 的简写。

举例:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <style type="text/css">
      p {
        color: red;
      }
    </style>
    <script>
      window.onload = function () {
        var oUser = document.getElementById("user");
        var oPwd = document.getElementById("pwd");
        var oBtn = document.getElementById("btn");
        var oMes = document.getElementById("mes");
        //页面一打开时,使用getItem()方法获取数据
        oMes.innerHTML =
          "账号:" +
          sessionStorage.getItem("user") +
          "<br/>密码:" +
          sessionStorage.getItem("pwd");
        //点击按钮后,使用setItem()方法设置数据
        oBtn.onclick = function () {
          sessionStorage.setItem("user", oUser.value);
          sessionStorage.setItem("pwd", oPwd.value);
          oMes.innerHTML = "账号:" + oUser.value + "<br/>密码:" + oPwd.value;
        };
      };
    </script>
  </head>
  <body>
    账号:<input id="user" type="text" /><br />
    密码:<input id="pwd" type="text" />
    <input id="btn" type="button" value="设置" />
    <p id="mes" style="color: red"></p>
  </body>
</html>

分析:

在页面一打开时,我们就使用 getItem() 方法来获取数据,由于键名为 user 和键名为 pwd 的这两个 ke y没有值,因此都为 null。

当在文本框中输入内容,然后点击【设置】按钮后,我们使用 setItem() 方法设置数据

当我们关闭当前页面(注意是只需要关闭当前页面,而不需要关闭浏览器),然后重新打开页面时,此时会发现 sessionStorage 数据并没有保存下来,如图所示。并且打开控制台也找不到sessionStorage 保存的数据。

对于 localStorage 和 sessionStorage,我们可以总结出以下4点:

  • localStorage 和 sessionStorage 都是 window 对象下的子对象。
  • 两者具有完全相同的操作,比如获取数据使用的是 getItem(),保存数据使用的是 setItem() 等。
  • localStorage对象保存的是“永久数据”,而 sessionStorage 对象保存的是“临时数据”。
  • 在实际开发中,localStorage 用得比较多,sessionStorage 很少用到,我们只需要重点掌握 localStorage 就行。

indexedDB

HTML5 新增了一种被称为 indexedDB 的数据库,该数据库是一种存储在客户端本地的 NoSQL 数据库,用于在本地存储大量数据。目前主流浏览器的最新版本都对其提供了支持。

indexedDB 是一个“对象数据库”,而不是“关系数据库”,它相对于传统的关系数据库(如MySQL、SQL Server等)来说,功能简化了很多,但是已经足够满足实际开发需求了。

特别注意一点,HTML5 标准中的 Web SQL Database 实际上已经被废除,如果小伙伴们在其他地方看到,直接忽略即可。在本地数据库这个技术方向,最新的 HTML5 标准表示只支持 indexedDB。

  1. 操作“数据库”
  • 创建数据库

在 HTML5 中,我们使用 indexedDB 对象的 open() 方法来创建或者打开一个数据库。

var request = window.indexedDB.open(数据库名, 版本号);
request.onerror = function(){
  console.log("创建或打开数据库失败!");
};
request.onsuccess = function(e){
  console.log("创建或打开数据库成功!");
};

indexedDB 对象是 window 对象下的一个子对象,我们可以使用 indexedDB 对象的 open() 方法来创建或打开一个数据库。

open() 方法有两个参数:第1个参数是数据库名;第2个参数是数据库版本号。其中版本号可以随便取,你可以取 “1.0”,也可以取 “20170804” 等。

如果数据库已经存在,则 open() 方法表示打开数据库;如果数据库不存在,则 open() 方法表示创建数据库。

window.indexedDB.open() 方法返回一个请求对象,我们将其赋值给变量 request。该请求对象有两个事件:onerror 事件和 onsuccess 事件。onerror 事件表示请求失败时触发的事件,onsuccess 事件表示请求成功时触发的事件。

举例:创建或打开数据库

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      var request = window.indexedDB.open("mydb", 1.0);
      request.onerror = function () {
        console.log("创建或打开数据库失败!");
      };
      request.onsuccess = function (e) {
        console.log("创建或打开数据库成功!");
        var db = e.target.result;
        console.log(db);
      };
    </script>
  </head>
  <body></body>
</html>

分析:

e.target.result 获取的是一个 IDBDatabase 对象。通过 IDBDatabase 对象,我们可以获取数据库的各种信息如数据库名、版本号等。简单来说,e.target.result 获取的就是我们刚刚创建或者打开的数据库。

这个 IDBDatabase 对象非常重要,其中数据库的增删查改操作,都是基于这个对象的

实际上,我们在控制台也能找到新创建的数据库 “mydb”

  • 删除数据库

在 HTML5 中,我们可以使用 indexedDB 对象的 deleteDatabase() 方法来删除数据库。

var request = window.indexedDB.deleteDatabase(数据库名);
request.onerror = function(){
  console.log("删除数据库失败!");
};
request.onsuccess = function(e){
  console.log("删除数据库成功!");
};

deleteDatabase() 方法有一个参数,这个参数是数据库名。跟 open() 方法一样,deleteDatabase() 方法同样会返回一个请求对象。该请求对象也有两个事件:onerror 事件和 onsuccess 事件。onerror 事件表示请求失败所触发的事件,onsuccess 事件表示请求成功所触发的事件。

举例:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      var request = window.indexedDB.deleteDatabase("mydb");
      request.onerror = function () {
        console.log("删除数据库失败!");
      };
      request.onsuccess = function (e) {
        console.log("删除数据库成功!");
      };
    </script>
  </head>
  <body></body>
</html>

分析:

使用 deleteDatabase() 方法删除数据库后,我们再去查看控制台,会发现数据库已经被删除了

执行删除数据库操作后,如果发现 “mydb” 数据库依旧存在,可能是因为 indexedDB 没有刷新,在【indexedDB】选项上面单击鼠标右键,然后点击【Refresh indexedDB】即可实现刷新,

  1. 操作“对象仓库”

接触过 SQL 的小伙伴都知道,创建了数据库后,接着肯定就是创建一个“表”来存储数据。但是在 indexedDB 中,是没有“表”这个概念的,而是用“对象仓库(Object Store)”来代替。我们一定要时刻记住:在 indexedDB 中,一个对象仓库就是一张表。

在 indexedDB 中,我们可以使用 IDBDatabase 对象的 createObjectStore() 方法来创建一个新的对象仓库。

var request = window.indexedDB.open(数据库名, 版本号);
request.onerror = function(){
  console.log("创建或打开数据库失败!");
};
request.onsuccess = function(){
  console.log("创建或打开数据库成功!");
};
request.onupgradeneeded=function(e){
  var db = e.target.result;
  //如果数据库中不包含该对象仓库,则创建新的对象仓库
  if(!db.objectStoreNames.contains("对象仓库名")){
    var store = db.createObjectStore("对象仓库名",{keyPath:"主键名"});
    for(var i = 0 ; i < data.length;i++){
      var addRequest = store.add(data[i]);
      addRequest.onerror = function(){
        console.log("添加数据失败!")
      };
      addRequest.onsuccess = function(){
        console.log("添加数据成功!")
      };
    }
  }
};

实际上,请求对象 request 除了 onerror 和 onsuccess 这两个事件外,还有一个 onupgradeneeded 事件,它表示版本号更新时触发的事件。对于对象仓库的创建,我们一般都是在 onupgradeneeded 事件中操作的。

e.target.result 获取的也是一个 IDBDatabase 对象,db.objectStoreNames.contains(“对象仓库名”) 表示判断某一个对象仓库是否存在。

var store = db.createObjectStore("对象仓库名",{keyPath:"主键名"});

在上面这一句代码中,使用 IDBDatabase 对象的 createObjectStore() 方法来创建一个新的对象仓库。createObjectStore() 方法有两个参数:第1个参数是“对象仓库名”;第2个参数用于设置对象仓库的主键。如果你想要让主键是一个递增的数字,可以使用下面这一句代码:

var store = db.createObjectStore("对象仓库名",{autoIncrement:true});

此外,db.createObjectStore() 方法返回一个 ObjectStore 对象。简单来说,ObjectStore 对象就是我们刚刚创建的对象仓库。

for(var i = 0 ; i < data.length;i++){
  var addRequest = store.add(data[i]);
  addRequest.onerror = function(){
    console.log("添加数据失败!")
  };
  addRequest.onsuccess = function(){
    console.log("添加数据成功!")
  };
}

在上面这段代码中,我们使用循环并且结合 ObjectStore 对象的 add() 方法往对象仓库中添加数据。store.add() 同样会返回一个请求对象。该请求对象也有两个事件:onerror 和 onsuccess。onerror 表示添加数据失败时所触发的事件,onsuccess 表示添加数据成功时所触发的事件。

举例:创建对象仓库(相当于创建一个“表”)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      //定义对象仓库的数据
      var data = [
        {
          id: 1001,
          name: "Byron",
          age: 24,
        },
        {
          id: 1002,
          name: "Frank",
          age: 30,
        },
        {
          id: 1003,
          name: "Aaron",
          age: 26,
        },
      ];
      //一定要更新版本号,以便触发onupgradeneeded事件
      var request = window.indexedDB.open("mydb", 2.0);
      request.onerror = function () {
        console.log("创建或打开数据库失败!");
      };
      request.onsuccess = function (e) {
        console.log("创建或打开数据库成功!");
      };
      request.onupgradeneeded = function (e) {
        var db = e.target.result;
        //如果数据库不包含"students"这张表,则创建新表
        if (!db.objectStoreNames.contains("students")) {
          var store = db.createObjectStore("students", { keyPath: "id" });
          for (var i = 0; i < data.length; i++) {
            var addRequest = store.add(data[i]);
            addRequest.onerror = function () {
              console.log("添加数据失败!");
            };
            addRequest.onsuccess = function () {
              console.log("添加数据成功!");
            };
          }
        }
      };
    </script>
  </head>
  <body></body>
</html>

分析:

创建对象仓库,都是在 onupgradeneeded 事件中执行的。因此,我们必须更新数据库版本号,以便触发 onupgradeneeded 事件。

执行创建对象仓库操作后,我们在控制台可以找到新创建的对象仓库 “students”(记得刷新indexedDB),如图所示

  1. 增删改查

在 indexed DB中,当想要使用对象仓库进行增删查改操作时,我们都需要开始一个事务。事务,简单来说就是“一组操作步骤”。这组操作步骤要么全部执行,要么一步也不执行。

大家记住一点就可以了:凡是涉及对象仓库的增删查改,都是使用事务来处理。

在 indexedDB 中,我们可以使用事务的 add() 方法来为对象仓库增加数据。

request.onsuccess = function(e){
  console.log("创建或打开数据库成功!");
  var db = e.target.result;
  var transaction = db.transaction(["students"],"readwrite");
  var store = transaction.objectStore("students");
  for(var i = 0 ; i < data.length;i++){
    var dataRequest = store.add(data[i]);
    dataRequest.onerror = function(){
      console.log("添加数据失败!");
    };
    dataRequest.onsuccess = function(){
      console.log("添加数据成功!");
    };
  }
};

凡是对象仓库的增删查改,都是在请求对象 request 的 onsuccess 事件中操作的。

var transaction = db.transaction(["students"],"readwrite");

上面这句代码中,表示使用IDBDatabase对象的transaction()方法开启一个事务,返回的是一个事务对象,即transaction对象。transaction()方法有两个参数:第1个参数是“对象仓库名”,它是“字符串数组”;第2个参数是“事务模式”,有两个取值。

① “read”:只读;

② “readwrite”:可读写。

var store = transaction.objectStore("students");

在上面这句代码中,调用 transaction 对象的 objectStore() 方法来连接对象仓库。objectStore() 方法有一个参数,表示“对象仓库名”。

var dataRequest = store.add(data[i]);

在上面这句代码中,调用 objectStore 对象的 add() 方法来为对象仓库添加数据,该方法返回一个请求对象。这个请求对象也有两个事件:onerror 和 onsuccess。

举例:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      //定义新的数据
      var data = [
        {
          id: 1004,
          name: "helicopter",
          age: 25,
        },
        {
          id: 1005,
          name: "winne",
          age: 21,
        },
        {
          id: 1006,
          name: "yuki",
          age: 22,
        },
      ];
      var request = window.indexedDB.open("mydb", 2.0);
      request.onerror = function () {
        console.log("创建或打开数据库失败!");
      };
      request.onsuccess = function (e) {
        console.log("创建或打开数据库成功!");
        var db = e.target.result;
        //开启事务
        var transaction = db.transaction(["students"], "readwrite");
        //连接对象仓库
        var store = transaction.objectStore("students");
        //添加新数据
        for (var i = 0; i < data.length; i++) {
          var dataRequest = store.add(data[i]);
          dataRequest.onerror = function () {
            console.log("添加数据失败!");
          };
          dataRequest.onsuccess = function () {
            console.log("添加数据成功!");
          };
        }
      };
    </script>
  </head>
  <body></body>
</html>

分析:

执行“增”操作后,我们再去查看控制台,会发现新的数据已经添加到对象仓库中了,

增加数据跟创建新表的操作很相似,不过两者也有明显的区别:增加数据使用的是 transaction() 方法,而创建新表使用的是 createObjectStore() 方法。

在 indexedDB 中,我们可以使用事务的 delete() 方法来删除对象仓库的数据。

request.onsuccess = function(e){
  console.log("创建或打开数据库成功!");
  var db = e.target.result;
  var transaction = db.transaction(["students"],"readwrite");
  var store = transaction.objectStore("students");
  var dataRequest = store.delete(1001);
  dataRequest.onerror = function(){
    console.log("删除数据失败!");
  };
  dataRequest.onsuccess = function(){
    console.log("删除数据成功!");
  };
};

对象仓库的“删”操作,也是在请求对象 request 的 onsuccess 事件中操作的。

var dataRequest = store.delete(1001);

在上面这句代码中,调用 objectStore 对象的 delete() 方法来为对象仓库删除数据,这个方法只有一个参数,这个参数是主键名。delete() 方法返回一个请求对象,这个请求对象也有两个事件:onerror 和 onsuccess。

举例:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      var request = window.indexedDB.open("mydb", 2.0);
      request.onerror = function () {
        console.log("创建或打开数据库失败!");
      };
      request.onsuccess = function (e) {
        console.log("创建或打开数据库成功!");
        var db = e.target.result;
        var transaction = db.transaction(["students"], "readwrite");
        var store = transaction.objectStore("students");
        var dataRequest = store.delete(1001);
        dataRequest.onerror = function () {
          console.log("删除数据失败!");
        };
        dataRequest.onsuccess = function () {
          console.log("删除数据成功!");
        };
      };
    </script>
  </head>
  <body></body>
</html>

分析:

执行“删”操作后,我们再去查看控制台,会发现 id 为 “1001” 的数据已经从对象仓库中删除了,

在 indexedDB 中,我们可以使用事务的 get() 方法来查询对象仓库的数据。

request.onsuccess = function(e){
  console.log("创建或打开数据库成功") ;
  var db = e.target.result;
  var transaction = db.transaction(["students"],"readwrite");
  var store = transaction.objectStore("students");
  var dataRequest = store.get(主键名);
  dataRequest.onerror = function(){
    alert("获取数据失败");
  };
  dataRequest.onsuccess = function(){
    if(this.result == undefined){
      console.log("没有符合条件的数据");
    }else{
      console.log(this.result);
    }
  };
};

对象仓库的“查”操作,也是在请求对象 request 的 onsuccess 事件中操作的。

var dataRequest = store.get(1002);

上面这句代码中,调用 objectStore 对象的 get() 方法来为对象仓库查询数据,这个方法只有一个参数,这个参数是主键名。get() 方法返回一个请求对象,这个请求对象也有两个事件:onerror 和 onsuccess。

举例:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      var request = window.indexedDB.open("mydb", 2.0);
      request.onerror = function () {
        console.log("创建或打开数据库失败!");
      };
      request.onsuccess = function (e) {
        console.log("创建或打开数据库成功");
        var db = e.target.result;
        var transaction = db.transaction(["students"], "readwrite");
        var store = transaction.objectStore("students");
        var dataRequest = store.get(1002);
        dataRequest.onerror = function () {
          alert("获取数据失败");
        };
        dataRequest.onsuccess = function () {
          if (this.result == undefined) {
            console.log("没有符合条件的数据");
          } else {
            console.log(this.result);
          }
        };
      };
    </script>
  </head>
  <body></body>
</html>

在 indexedDB 中,我们可以使用事务的 put() 方法来更新对象仓库的数据。

request.onsuccess = function(e){
  var db = e.target.result;
  console.log("创建或打开数据库成功") ;
  var transaction = db.transaction(["students"],"readwrite");
  var store = transaction.objectStore("students");
  var value = {
    //...
  }
  var dataRequest = store.put(value);
  dataRequest.onerror = function(){
    console.log("更新数据失败!");
  };
  dataRequest.onsuccess = function(){
    console.log("更新数据成功!");
  };
};

对象仓库的“改”操作,也是在请求对象 request 的 onsuccess 事件中操作的。

var dataRequest = store.put(value);

在上面这句代码中,调用 objectStore 对象的 put() 方法来为对象仓库更新数据,这个方法只有一个参数,这个参数是一条数据记录。put() 方法返回一个请求对象,这个请求对象也有两个事件:onerror 和 onsuccess。

举例:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title></title>
  <script>
    var request = window.indexedDB.open("mydb",2.0);
    request.onerror = function(){
      console.log("创建或打开数据库失败!");
    };
    request.onsuccess = function(e){
      var db = e.target.result;
      console.log("创建或打开数据库成功") ;
      var transaction = db.transaction(["students"],"readwrite");
      var store = transaction.objectStore("students");
      var value = {
        id:1002,
        age:40,
        name:"Jack"
      }
      var dataRequest = store.put(value);
      dataRequest.onsuccess = function(){
        console.log("更新数据成功!");
      };
      dataRequest.onerror = function(){
        console.log("更新数据失败!");
      };
    };
  </script>
</head>
<body>
</body>
</html>

分析:

执行“改”操作后,我们再去查看控制台,会发现 id 为 1002 的数据已经被更新了,

  • 清空

在 indexedDB 中,我们可以使用事务的 clear() 方法来清空对象仓库的数据。

request.onsuccess = function(e){
  var db = e.target.result;
  console.log("创建或打开数据库成功") ;
  var transaction = db.transaction(["students"],"readwrite");
  var store = transaction.objectStore("students");
  var dataRequest = store.clear();
  dataRequest.onerror = function(){
    console.log("清空数据失败!");
  };
  dataRequest.onsuccess = function(){
    console.log("清空数据成功!");
  };
};

对象仓库的“清空”操作,也是在请求对象 request 的 onsuccess 事件中操作的。

var dataRequest = store.clear();

在上面这句代码中,调用 objectStore 对象的 clear() 方法来清空对象仓库中的所有数据,这个方法没有参数。clear() 方法返回一个请求对象,这个请求对象也有两个事件:onerror 和 onsuccess。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      var request = window.indexedDB.open("mydb", 2.0);
      request.onerror = function () {
        console.log("创建或打开数据库失败!");
      };
      request.onsuccess = function (e) {
        var db = e.target.result;
        console.log("创建或打开数据库成功");
        var transaction = db.transaction(["students"], "readwrite");
        var store = transaction.objectStore("students");
        var dataRequest = store.clear();
        dataRequest.onerror = function () {
          console.log("清空对象仓库失败!");
        };
        dataRequest.onsuccess = function () {
          console.log("清空对象仓库成功!");
        };
      };
    </script>
  </head>
  <body></body>
</html>

分析:

执行“清空”操作后,我们再去查看控制台,会发现对象仓库中的所有数据已经被清空了

实战:计数器

根据 localStorage 和 sessionStorage 的特点,localStorage 可以作为Web应用访问计数器,而 sessionStorage 可以作为会话计数器。下面我们来具体实现一下。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      if (localStorage.getItem("count")) {
        n = Number(localStorage.getItem("count")) + 1;
        localStorage.setItem("count", n);
      } else {
        localStorage.setItem("count", 1);
      }
      console.log("页面总访问数:" + localStorage.count);
    </script>
  </head>
  <body></body>
</html>

- Book Lists -