html5中LocalStorage、SessionStorage、WebSQL、COOKIEs、IndexedDB、SQLite对比及代码
在html5发布之前,html中常用的存储方式是COOKIE,但是COOKIE由于存储大小的限制,一般不超过4kb,所以对于html的发展有制约,因此在html5中新增了LocalStorage、SessionStorage、WebSQL、IndexedDB、SQLite五种离线客户端存储技术,今天我们一个一个分析介绍一下用法及示例代码。
(一) LocalStorage
LocalStorage 存储的数据保存在浏览器中。存储容量很小,大概不会超过5M(不同的浏览器有差别),它是以键值对形式保存数据的,没有关联查询、条件查询的机制。
<html> <head> <title>localStorage</title> </head> <body> <script> const Storage = {}; Storage.get = function(name) { return localStorage.getItem(name); } Storage.set = function(name, val) { localStorage.setItem(name, val); } Storage.del = function(name) { localStorage.removeItem(name); } Storage.set("status", "OK"); Storage.set("quit", "..."); //Storage.del("status"); </script> </body> </html>
(二) SessionStorage
SessionStorage 跟 LocalStorage 很相似,大小不超过5M,区别是每次关闭会话,其中的内容会被清空。在窗口中打开页面会复制顶级浏览会话的上下文作为新会话的上下文。相同 url 的不同 tabs 页面,其中的值是不同的。有过期时间设置,想持久化存储数据,它是做不到的。
<html> <head> <title>sessionStorage</title> </head> <body> <script> const Storage = {}; Storage.get = function(name) { return sessionStorage.getItem(name); } Storage.set = function(name, val) { sessionStorage.setItem(name, val); } Storage.del = function(name) { sessionStorage.removeItem(name); } Storage.set("status", "OK"); Storage.set("quit", "..."); //Storage.del("status"); </script> </body> </html>
(三) WebSQL
Web SQL 数据库API 并不是 HTML5 规范的一部分,但是它是一个独立的规范。WebSQL 是在浏览器上模拟数据库,使用 js 来操作 SQL 完成对数据的读写,websql的底层实现还是sqlite数据库。他的大小默认是50M,当超过时浏览器会弹出是否允许扩容提示,每次可扩容5M。
websql封装代码如下:
<script type="text/javascript"> /** *数据库操作辅助类,定义对象、数据操作方法都在这里定义 */ var dbname='dbname';/*数据库名*/ var dbdesc = '测试数据库'; /*数据库描述*/ var dbsize = 20*1024*1024; /*数据库大小*/ var dataBase = null; /*暂存数据库对象*/ /*数据库中的表单名*/ var websqlTable = "websqlTable"; /** * 打开数据库 * @returns dataBase:打开成功 null:打开失败 */ function websqlOpenDB(){ /*数据库有就打开 没有就创建*/ var version = window.localStorage.DBversion; dataBase = window.openDatabase(dbname, version, dbdesc, dbsize); if (dataBase) { console.log("数据库创建/打开成功!"); } else{ console.log("数据库创建/打开失败!"); } return dataBase; } //修改数据库版本 function changeDataBaseVersion(old_version,new_version){ var db = websqlOpenDB(); db.changeVersion(old_version,new_version,null,function(err){},null) window.localStorage.DBversion = new_version; } /** * 新建数据库里面的表单 * @param tableName:表单名 */ function websqlCreatTable(tableName){ // chinaAreaOpenDB(); var creatTableSQL = 'CREATE TABLE IF NOT EXISTS '+ tableName+'(ID text,QUESTION text)'; dataBase.transaction(function (ctx,result) { ctx.executeSql(creatTableSQL,[],function(ctx,result){ console.log("表创建成功 " + tableName); },function(tx, error){ console.log('创建表失败:' + tableName + error.message); }); }); } //插入数据 function websqlInsterDataToTable(tableName,id,question){ var question = JSON.stringify(question); var insterTableSQL = 'INSERT INTO ' + tableName + ' VALUES (?,?)'; dataBase.transaction(function (ctx) { ctx.executeSql(insterTableSQL,[id,question],function (ctx,result){ console.log("插入" + tableName + id + "成功"); }, function (tx, error) { console.log('插入失败: ' + error.message); }); }); } /** * 获取数据库一个表单里面的所有数据 * @param tableName:表单名 * 返回数据集合 */ function websqlGetAllData(tableName,fn){ var selectALLSQL = 'SELECT * FROM ' + tableName; dataBase.transaction(function (ctx) { ctx.executeSql(selectALLSQL,[],function (ctx,result){ console.log('查询成功: ' + tableName +'__'+ result.rows.length); var len = result.rows.length; var queryDataArray = []; for(var i = 0;i < len;i++) { queryDataArray.push(JSON.parse(result.rows.item(i).QUESTION)); } fn(queryDataArray); }, function (tx, error) { console.log('查询失败: ' + error.message); }); }); } //查询所有数据,获取json格式 function websqlGetAllDataJson(tableName,fn){ var selectALLSQL = 'SELECT * FROM ' + tableName; dataBase.transaction(function (ctx) { ctx.executeSql(selectALLSQL,[],function (ctx,result){ console.log('查询成功: ' + tableName +'__'+ result.rows.length); var len = result.rows.length; var queryDataArray = {}; for(var i = 0;i < len;i++) { var id = result.rows.item(i).ID; id = id.replace('.0',''); queryDataArray[id] = JSON.parse(result.rows.item(i).QUESTION); } fn(queryDataArray); }, function (tx, error) { console.log('查询失败: ' + error.message); }); }); } /** * 获取数据库一个表单里面的部分数据 * @param tableName:表单名 * @param name:姓名 */ function websqlGetAData(tableName,id,fn){ var selectSQL = 'SELECT * FROM ' + tableName + ' WHERE ID = ?' dataBase.transaction(function (ctx) { ctx.executeSql(selectSQL,[id+'.0'],function (ctx,result){ fn && fn(JSON.parse(result.rows.item(0).QUESTION)) }, function (tx, error) { console.log('查询失败: ' + error.message); }); }); } function webSqlDeleteTable(tabName){ dataBase.transaction(function(tx) { tx.executeSql('DROP TABLE '+tabName+''); console.log('删除表'+tabName+'成功') }, function(tx,err){ console.log('删除表'+tabName+'失败') }) } /** * 删除表单里的全部数据 * @param tableName:表单名 */ function websqlDeleteAllDataFromTable(tableName){ var deleteTableSQL = 'DELETE FROM ' + tableName; localStorage.removeItem(tableName); dataBase.transaction(function (ctx,result) { ctx.executeSql(deleteTableSQL,[],function(ctx,result){ console.log("删除表成功 " + tableName); },function(tx, error){ console.log('删除表失败:' + tableName + error.message); }); }); } websqlOpenDB(); websqlCreatTable("test"); </script>
(四) COOKIEs
COOKIEs 存储容量太小,只能存 4kb 的内容,而且每次与服务端交互,同域下的 COOKIE 还会被携带到服务端,也没有关联查询、条件查询的机制。(四) COOKIEsCOOKIEs 存储容量太小,只能存 4kb 的内容,而且每次与服务端交互,同域下的 COOKIE 还会被携带到服务端,也没有关联查询、条件查询的机制。
js操作COOKIE代码封装示例:
<script type="text/javascript"> function setCOOKIE(cname,cvalue,exdays){ var d = new Date(); d.setTime(d.getTime()+(exdays*24*60*60*1000)); var expires = "expires="+d.toGMTString(); document.COOKIE = cname+"="+cvalue+"; "+expires; } function getCOOKIE(cname){ var name = cname + "="; var ca = document.COOKIE.split(';'); for(var i=0; i<ca.length; i++) { var c = ca[i].trim(); if (c.indexOf(name)==0) { return c.substring(name.length,c.length); } } return ""; } function checkCOOKIE(){ var user=getCOOKIE("username"); if (user!=""){ alert("欢迎 " + user + " 再次访问"); } else { user = prompt("请输入你的名字:",""); if (user!="" && user!=null){ setCOOKIE("username",user,30); } } } </script>
(五) IndexedDB
IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据。该 API 使用索引实现对数据的高性能搜索。
IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。 然而,不像 RDBMS 使用固定列表,IndexedDB 是一个基于 js 的面向对象数据库。IndexedDB 可以存储和检索用键索引的对象。只需要指定数据库模式,打开与数据库的连接,然后检索和更新一系列事务。
而且您无需担心indexedDB中的可用存储空间,因为它的容量更高。
最大存储容量取决于两个因素,浏览器和磁盘空间。
因此,Chrome和大多数基于铬的浏览器允许使用80%的磁盘空间,而每个来源可以使用其中的75%。就是说 如果您有100GB的磁盘空间,那么80GB可用于将数据存储在indexedDB中,而60GB的空间可用于单个源。
此外, Firefox 允许每个来源存储2GB数据, Safari 允许每个来源存储1GB。
您可以按以下方式检查可用空间和已用空间的总和-
const quota = await navigator.storage.estimate(); const totalSpace = quota.quote; const usedSpace = quote.used;
indexeddb示例代码如下:
<script type="text/javascript"> if ('indexedDB' in window) { // 如果数据库不存在则创建,如果存在但是version更大,会自动升级不会复制原来的版本 var req = indexedDB.open("TestDB", 1); req.onupgradeneeded = function(e) { var db = req.result; // var store = db.createObjectStore("student", {autoIncrement: true}); 使用自增键 // 创建student表 var store = db.createObjectStore("student", {keyPath: 'id'}); // 设置id为主键 store.createIndex('student_id_unqiue','id', {unique: true}); } req.onsuccess = function(event) { var students = [ {id: 1, name: '小叶', age: '11'}, {id: 2, name: '小王', age: '12'}, {id: 3, name: '小张', age: '13'} ]; var db = event.target.result; // var transaction = db.transaction('student', 'readwrite'); var transaction = db.transaction(['student'], 'readwrite'); transaction.onsuccess = function(event) { console.log('[Transaction] 好了!'); }; var studentsStore = transaction.objectStore('student'); students.forEach(function(student){ var db_op_req = studentsStore.add(student); db_op_req.onsuccess = function() { console.log("存好了"); } }); studentsStore.count().onsuccess = function(event) { console.log('学生个数', event.target.result); }; // 获取id为1的学生 studentsStore.get(1).onsuccess = function(event) { console.log('id为1的学生', event.target.result); }; // 更新id为1的学生 students[0].name = '小小叶'; studentsStore.put(students[0]).onsuccess = function(event) { console.log('更新id为1的学生姓名', event.target.result); }; // 删除id为2的学生 studentsStore.delete(2).onsuccess = function(event) { console.log('id为2的学生已经删除'); }; } req.onerror = function() { console.log("数据库出错"); } }else{ console.log('你的浏览器不支持IndexedDB'); } </script>
(六) SQLite
SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,我们不需要在系统中配置。
就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。
下面直接在浏览器中创建一个sqlite数据库文件并下载到本地。
示例代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/sql.js"></script> </head> <body> <button name="test" type="button" value="val"BfwOnclick="save()">下载sqlite数据库</button> <input id="uploadInput" type="file"BfwOnchange="getfile()"> </body> <script> function save() { //Create the database var db = new window.SQL.Database(); db.run("CREATE TABLE test (列1 int, 列2 char);"); db.run("INSERT INTO test VALUES (0,'hello');"); db.run("INSERT INTO test VALUES (1,'world');"); db.run("INSERT INTO test VALUES (55,'34534545');"); db.run("INSERT INTO test VALUES (166,'woteggrgrld');"); //save to local file var data = db.export(); var arraybuff = data.buffer; var blob = new Blob([arraybuff]); var url = window.URL.createObjectURL(blob); var a = document.createElement("a"); a.href = url; a.download = 'test.db'; a.click(); window.URL.revokeObjectURL(url); } function getfile() { var files = document.getElementById("uploadInput").files;//document.getElementById("uploadInput").value; var file = files[0]; var fr = new FileReader(); fr.onload = function(){ var Uints = new Uint8Array(fr.result); var db = new window.SQL.Database(Uints); var res = db.exec("SELECT 列2 FROM test"); for(i=0;i<res[0].values.length;i++) {//query values console.log(res[0].values[i]+' '); } } fr.readAsArrayBuffer(file); } </script> </html>
网友评论0