最近发现系统中用到了浏览器本地存储实现 cache。这里做一下整理。
Web Storage
我们知道 H5 新增了一个在客户端本地保存数据的 Web Storage 功能。一共有两种:localStorage - 没有时间限制的数据存储
sessionStorage - 针对一个 session 的数据存储
而之前这些存储都是由 cookie 完成的。但是 cookie 有以下缺点:
大小: cookies大小一般被限制在 4KB。
带宽: cookies是随HTTP 事务一起被发送的,因此会浪费一部分发送cookies 时使用的带宽。
复杂性: 要正确地操纵cookies是很困难的。
localStorage
localStorage 用于永久保存数据在客户端。打开浏览器输入 localStorage。如下:
从上面看出localStorage 有很多函数,
函数 | 作用 |
clear() | 清空localStorage存储的数据 |
getItem(key) | 读取数据 |
hasOwnProperty(key) | localStorage上是否利用 key保存了数据 |
key(index) | 读取某个 index 的键值(从0开始计数) |
length | localStorage存储变量的个数 |
propertyIsEnumerable(key) | 返回一个布尔值,表明指定的属性名是否是当前对象可枚举的自身属性 |
removeItem(key) | 删除某个具体变量 |
setItem(key, value) | 存储数据 |
toLocaleString() | 将(数组)转为本地字符串 |
valueOf() | 获取所有存储的数据 |
sessionStorage
所谓session,是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。session对象可以用来保存这段时间内所要保存的任何数据。sessionStorage 的函数功能类似。
存取数据
var person = {
name: 'zhangsan',
age: 20,
sex: 'male'
}
// 存数据
var info = JSON.stringify(person);
localStorage.setItem('zhangsan', info);
// 获取数据
var str = localStorage.getItem('zhangsan');
var dbData = JSON.parse(str);
console.log(dbData);
从下面的输出看,localStorage 确实很好的完成了对象的存取。
遍历
两个存储的遍历都很简单,先用 key(i) 获取 key 的集合,然后遍历。
// 遍历
for (var i=0, len = localStorage.length; i < len; i++) {
var key = localStorage.key(i);
var value = localStorage.getItem(key);
console.log(key + "=" + value);
}
var storage = window.sessionStorage;
for (var i=0, len = storage.length; i < len; i++) {
var key = storage.key(i);
var value = storage.getItem(key);
console.log(key + "=" + value);
}
其实这里还有个很神奇的地方,有知道的大神欢迎指教。
控制台输入 localStorage 时,原型中有个 函数名字 是 get 加空格 加 length。没搞懂是做什么的,怎么用。
本地数据库
另外H5 也提供了本地数据库。在这之前数据库只能存在服务器端。有了本地数据库后,浏览器可以用SQL语言访问数据库了。
主要有两步:
1. 创建访问数据库的对象
2. 使用事务处理
创建数据库
// 创建数据库访问对象
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
// 第一个参数,数据库名,
// 第二个为版本号,
// 第三个为数据库描述
// 第四个为数据库大小。
// 返回数据库访问对象,若数据库不存在,则创建。
事务处理
创建表
利用数据库访问对象创建表,注意 CREATE TABLE IF NOT EXISTS 这样当表已经存在时,就不会重复创建了。// 创建表
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS(id unique, message TEXT)');
});
插入数据
注意插入数据时,如果 sql 语句里面需要参数 用 ? 代替,然后在 参数数组中传参
// 插入数据 (sql语句, 参数数组)
db.transaction(function (tx) {
tx.executeSql('INSERT INTO LOGS VALUES(?, ?)', [1, 'I am message']);
});
查询
跟上面一样,查询也可以传参数,这里我留空了。
// 查询
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM LOGS', [], function(transaction, results){
console.log(results);
});
});
最后你就能在控制台看到如下输出了:
这里可能有点疑惑了。 其实 results 的 rows 属性才是我们的数据集合。不过从下面的代码可以发现 rows也只是个类数组而已。
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM LOGS', [], function(transaction, results){
console.log(typeof results.rows);
console.log(results.rows instanceof Array);
for (var i = 0; i < results.rows.length; i++) {
console.log(results.rows[i]);
}
});
});
语法
首先为了防止我们正在访问的数据被修改,所有的数据库访问应该加事务,即调用数据库访问对象的 transaction() 方法。语法如下
db.transaction(function (tx) {
// TODO
});
之后在这个回调里面执行访问数据库的语句。
tx.executeSql(sqlquery, [], dataHandler, errorHandler);
// 例如
// tx.executeSql("UPDATE people set age=? where name=?;", [age, name], dataHandler, errorHandler);
这里需要四个参数:
1. sql语句
2. sql需要的参数数组
3. sql执行后,要执行的回调
4.sql执行失败后,要进行的错误处理程序
function dataHandler(transaction, results) {
// results : 查询到的数据集结果
// TODO 处理成功的返回的结果
}
function errorHandler(transaction, errmsg) {
// transaction 对象,
// errmsg : 执行发生错误是的错误信息文字。
}
调试工具
Chrome 浏览器自带的调试工具可以很方便的检查我们的执行结果。按下 F12 后,可以如图看下刚才我们创建的表、插入的数据等。
这里,其他浏览器也是类似。不过前提是浏览器支持 HTML 5。否则报以下错误。比如我的 IE 11