前端数据缓存方案
参考文献: 前端数据库
最近工作上,有需求需要接触到将数据缓存到前端,研究了一番,在此记录,话不多说,直接进入正题:
一、使用localstorage或者sessionstorage实现缓存
1、先了解一下这是什么东西,打开浏览器,F12—Application,可以查看。

2、两者区别:
- localstorage和sessionstorage一般存储以键值对的形式存在。localstorage则是持久化在本地,只要你不主动删除,一直存在,sessionstorage则是以当前会话为期限,当前会话结束,数据自然清除,例如你关掉浏览器重新打开,数据就不见了。
- 值得关注的是两者的存储大小都是5M,超出限制,浏览器就报错了,所以缓存数据时要谨慎。
3、如何存储和取出数据?
值得注意的是一般都配合JSON.stringify()、JSON.parse()一起使用,localStorage和sessionStorage使用方法一致,这里介绍sessionStorage
存储: window.sessionStorage.setItem(key,value);
取出: window.sessionStorage.getItem(key);
代码如下:
<script type="text/javascript">
$(function () {
$.get("/user/findAll",function (data) {
//存储前将其他数据清除
sessionStorage.clear();
//将数据存入到前端缓存sessionStorage
window.sessionStorage.setItem("users",JSON.stringify(data));
});
});
function getData() {
//从sessionStorage取出数据
var userList = window.sessionStorage.getItem("users");
userList = JSON.parse(userList);
console.log(userList);
}
</script>
<body>
<input type="button" value="get data from sessionStorage" onclick="getData()">
看看效果图:

单击button取出数据:

二、将数据存储到webSql,当然这个目前只有Google支持。IE和火狐均不支持。
1、同样,先来个初识,F12同样可以查看,相当于前端的数据库,最大内存支持25M,要注意的是页面刷新数据库就消失了。

2、使用Api来完成对数据库的增、删、改、查。sql语句与后端操作数据库的一致。
核心Api包括:
创建数据库: openDatabase(dbName,version,description,db size,callback)
参数介绍: 数据库名称、数据版本、描述、数据库大小、创建成功回调(可省略)
打开事务: transaction(callback,success callback,error callback)
参数介绍: 三个都是回调,一般使用第一个足矣
执行sql: executeSql(sql,arguments,success callback,error callback)
参数介绍: sql语句、参数、成功回调、错误回调
完整代码:
要注意的是执行sql的方法(executeSql)必须放在事务(transaction)的回调里面执行。请仔细品下面代码,我把对数据库的每种操作抽出到单个方法内:
function testWebSql() {
//dbName、version、description、db size、callback
let db = openDatabase("db1", "1.0", "save data", 20 * 1024 * 1024);
create();
add();
update();
query();
remove();
//创建数据库
function create() {
let sql = "create table if not exists log(id primary,msg)";
//callback、success callback、error callback
db.transaction(function (ts) {
//create table
//sql、argument、success callback、error callback
ts.executeSql(sql, [],
(transaction, resultSet) => {
console.log("success")
},
(transaction, error) => {
console.log(error.message)
});
});
}
//插入数据
function add() {
let sql = "insert into log (id,msg) values(3,'add one data')";
db.transaction(function (ts) {
//sql、argument、success、error
ts.executeSql(sql, [],
(transaction, resultSet) => {
console.log("insert success")
},
(transaction, error) => {
console.log(error.message)
});
});
}
//更新数据
function update() {
let sql = "update log set msg = 'update data 3' where id=?";
db.transaction(function (ts) {
//sql、argument、success、error
ts.executeSql(sql, [1],
(transaction, resultSet) => {
console.log("update success")
},
(transaction, error) => {
console.log(error.message)
});
});
}
//查询数据
function query() {
let sql = "select * from log";
db.transaction(function (ts) {
//sql、argument、success、error
ts.executeSql(sql, [],
(transaction, resultSet) => {
console.log(resultSet.rows);
for (let i = 0; i < resultSet.rows.length; i++) {
console.log(resultSet.rows[i]);
}
},
(transaction, error) => {
console.log(error.message)
});
});
}
//删除
function remove() {
let sql = "delete from log where id=?";
db.transaction(function (ts) {
//sql、argument、success、error
ts.executeSql(sql, [1],
(transaction, resultSet) => {
console.log("delete success")
},
(transaction, error) => {
console.log(error.message)
});
});
}
}
三、将数据存储到索引库indexedDB
1、与webSql类似,但是不同的是indexedDB类似非关系型数据库,存储空间大,一般不小于250M。当然,既然是索引数据库,就可以通过建立索引来实现搜索,不过不支持sql语句对数据库的操作。

2、特点: 相比其他,存储空间大,键值对存储,异步设计(对数据库的操作是异步,则就是操作大量数据插入时不会锁死表,不拖慢网页),存储的数据不会自动清除,除非自己清除缓存。
3、讲讲用法,跟websql类似,也是调用Api,不过这个不支持sql语句。
重点: 研究过程中看过不少帖子,五花八门。后面才发现,对数据库的操作要放在成功回调的函数内才可以执行(也就是 request.onsuccess=function(){}),切记切记!!
function testIndexedDb() {
var db;
var objectStore;
//创建数据库
var request = window.indexedDB.open("db2",2);
//创建成功后,回调函数
request.onsuccess=function (event) {
db =request.result;
add();
update();
query();
queryById();
queryAll();
remove();
};
//失败时回调
request.onerror=function (event) {
console.log(event);
};
//数据版本发生改变时才会被调用
request.onupgradeneeded=function (event) {
console.log(event);
db = event.target.result;
objectStore = db.createObjectStore('person',{ keyPath: 'id' });
objectStore.createIndex('name','name',{unique: true})
};
//增
function add() {
let request = db.transaction(['person'],'readwrite')
.objectStore('person')
.add({ id: 2, name: '李四', age: 24, email: 'zhangsan@example.com' });
request.onsuccess=function (event) {
console.log(event);
};
request.onerror=function (event) {
console.log(event);
}
}
//改
function update() {
let request = db.transaction(['person'],'readwrite')
.objectStore('person')
.put({ id: 2, name: '李四', age: 25, email: 'lisi@example.com' });
request.onsuccess=function (event) {
console.log("update success");
};
request.onerror=function (event) {
console.log(event);
}
}
//根据id查询
function queryById() {
let request = db.transaction(['person'])
.objectStore('person')
.get(1);//根据id查询数据
request.onsuccess=function (event) {
console.log(event.target.result);
};
request.onerror=function (event) {
console.log(event);
}
}
//根据索引查询
function query() {
let request = db.transaction(['person'])
.objectStore('person').index('name')
.get("李四");//根据id查询数据
request.onsuccess=function (event) {
console.log(event.target.result);
};
request.onerror=function (event) {
console.log(event);
}
}
//查询全部
function queryAll() {
let request = db.transaction('person')
.objectStore('person')
.openCursor().onsuccess=function(event){
console.log(event);
var cursor =event.target.result;
if (cursor){
console.log("id: "+cursor.key);
console.log("name: "+cursor.value.name);
console.log("age: "+cursor.value.age);
console.log("email: "+cursor.value.email);
cursor.continue();
}
};
}
//删除
function remove() {
let request = db.transaction('person',"readwrite")
.objectStore('person')
.delete(2);
request.onsuccess=function (event) {
console.log("success");
};
request.onerror=function (event) {
console.log(event);
}
}
}
四、直接将数据存在页面(input标签)
相比上面的几种方法,这种避免了大小的限制。我觉得可行。
$(function () {
$.get("/user/findAll", function (data) {
//将数据存入到input标签
$("#projects").val(JSON.stringify(data));
});
});
function getData() {
//根据id取出标签的value属性值
var userList= $("#projects").val();
userList = JSON.parse(userList);
console.log(userList);
}
<body>
<input type="button" value="get data from sessionStorage" onclick="getData()">
<input type="hidden" id="projects">
</body>
点击button,获取数据:

综上,数据量小的时候我建议是用第一种(sessionStorage),一来会话结束自动清除缓存,减少对浏览器的压力,而且也能每次重新访问都获得最新数据,二来不用频繁操作数据库,我觉得用起来挺方便。数据量大的话,建议还是用最后一种吧(indexedDB),一个是内存足够大,二来也可以用索引搜索,会比较快。还有还有,如果想简单粗暴一点,就直接存页面好了。
希望可以帮到你!如有侵权,联系删除!
灰色稻草人
本文介绍了前端数据缓存的三种常见方案:使用localstorage和sessionstorage进行键值对存储,利用webSql创建前端数据库(仅Google支持),以及运用indexedDB实现大规模数据存储。针对不同数据量需求,作者推荐了适用的缓存方法,并提供了相关代码示例。
2623





