处理localStorage的9个库

HTML5 本地存储 API (Web 存储的一部分) 具有优秀的浏览器支持,正在被越来越多的应用使用。它有简单的API,和cookies类似,也有他的缺点。

在过去的一年左右我碰到过很多的工具和库使用本地存储 API,所以我在这篇文章中将他们集中起来,并通过一些代码示例来讨论他们的特性。

Lockr

Lockr 是本地存储 API 的包装,并允许您使用大量的有用的方法和特点。例如,虽然 localStorage 仅限于存储只有字符串,Lockr 可以让你存储不同的数据类型,而无需自己做转换:

1
2
3
4
Lockr.set('website', 'SitePoint'); // string
Lockr.set('categories', 8); // number
Lockr.set('users', [{ name: 'John Doe', age: 18 }, { name: 'Jane Doe', age: 19 }]);
// object

其他功能包括:

  • Lockr.get()方法检索所有key/value
  • 使用Lockr.getAll()将所有key/value编译成数组
  • 使用Lockr.flush()删除所有存储的key/value
  • 通过Lockr.saddLockr.srem使用key来添加和删除值

The Local Storage Bridge

1 KB 库,以便在同一个浏览器,使用本地存储作为通信信道的选项卡之间交换消息。在引用了这个库之后,这里的一些示例代码可以使用:

1
2
3
4
5
6
7
8
9
// send a message
lsbridge.send('my-namespace', {
message: 'Hello world!'
});
 
// listen for messages
lsbridge.subscribe('my-namespace', function(data) {
console.log(data); // prints: 'Hello world!'
});

如代码所示, send ()方法创建并发送消息和subscribe()方法允许您侦听指定的消息。你可以在这篇博客阅读更多关于库的信息。

Barn

这个库提供类似Redis的API,在本地存储API中提供“快速,原子持久存储层”。下面代码取自项目README文件。它演示了许多可用的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var barn = new Barn(localStorage);
 
barn.set('key', 'val');
console.log(barn.get('key')); // val
 
barn.lpush('list', 'val1');
barn.lpush('list', 'val1');
console.log(barn.rpop('list')); // val1
console.log(barn.rpop('list')); // val1
 
barn.sadd('set', 'val1');
barn.sadd('set', 'val1');
barn.sadd('set', 'val1');
console.log(barn.smembers('set')); // ['val1', 'val2', 'val3']
barn.srem('set', 'val3');
console.log(barn.smembers('set')); // ['val1', 'val2', 'val3']

API 的其他功能包括能够得到开始/结束值的范围,得到值数组,和压缩整个存储中数据以节省空间。repo有关于所有方法和他们做什么的完全参考手册

store.js

这是另一个包装,类似于 Lockr,但这一次通过提供支持回退来提供浏览器更深层次的支持。README解释到:“如果可用的时候,store.js使用localStorage,如果是IE6或IE7,或使用回userData。不会有造成你页面缓慢的碎片。没有让你网络请求臃肿的cookies。

在以下代码中的注释,解释了基本的 API:

1
2
3
4
5
6
7
8
9
10
11
// Store 'SitePoint' in 'website'
store.set('website', 'SitePoint');
 
// Get 'website'
store.get('website');
 
// Remove 'website'
store.remove('website');
 
// Clear all keys
store.clear();

此外,还有一些更高级的功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Store an object literal; uses JSON.stringify under the hood
store.set('website', {
name: 'SitePoint',
loves: 'CSS'
});
 
// Get the stored object; uses JSON.parse under the hood
var website = store.get('website');
console.log(website.name + ' loves ' + website.loves);
 
// Get all stored values
console.log(store.getAll());
 
// Loop over all stored values
store.forEach(function(key, val) {
console.log(key, val);
});

在 GitHub README中有很多关于浏览器支持和潜在的 bug 和陷阱深度细节 (例如,某些浏览器不允许在在私密模式下使用本地存储) 。

lscache

lscache 是另一个 localStorage 包装,但有几个额外的功能。你可以使用它作为简单的本地存储 API 或你可以使用模拟Memcached,内存对象缓存系统的功能。

lscache 公开代码中的注释所述的下列方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// set a greeting with a 2 minute expiration
lscache.set('greeting', 'Hello World!', 2);
 
// get and display the greeting
console.log(lscache.get('greeting'));
 
// remove the greeting
lscache.remove('greeting');
 
// flush the entire cache of items
lscache.flush();
 
// flush only expired items
lscache.flushExpired();

像前面的库,这个库也关注序列化,所以你可以通过以下方式存储和取回对象:

1
2
3
4
5
6
7
8
lscache.set('website', {
name: 'SitePoint',
'category': 'CSS'
}, 4);
 
// retrieve data from the object
console.log(lscache.get('website').name);
console.log(lscache.get('website').category);

最后lscache允许你将数据分割存放在“桶中”。看看这个代码:

1
2
3
4
5
6
7
8
lscache.set('website', 'SitePoint', 2);
console.log(lscache.get('website')); // 'SitePoint'
 
lscache.setBucket('other');
console.log(lscache.get('website')); // null
 
lscache.resetBucket();
console.log(lscache.get('website')); // 'SitePoint'

看到第二个log,返回的数据是null。因为我在打印结果log前设置了一个自定义桶。一旦我设置了一个桶,任何之前添加在Iscache中的数据将无法访问,即时我尝试删除。只有在“other”桶里面的数据可以访问或者删除。一旦当我重置了桶,我将可以重新访问之前的数据。

secStore.js

secStore.js数据存储API,它增加了一个可选的安全层,也称作Stanford Javascript Crypto Library. secStore.js允许你选择你存储的方式:localStorage,sessionStorage或cookies。为了使用secStore.js你必须包含之前提到的sjcl.js库。

这里有一个例子演示了如何使用encrypt选项来保存一些数据:

1
2
3
4
5
6
7
8
9
10
11
12
var storage = new secStore;
var options = {
encrypt: true,
data: {
key: 'data goes here'
}
};
 
storage.set(options, function(err, results) {
if (err) throw err;
console.log(results);
});

注意到set()方法被使用了,由你定义在opions属性中(包含自定义数据以及测试结果的callback函数)。我们可以稍后使用get()方法获取数据:

1
2
3
4
storage.get(options, function(err, results) {
if (err) throw err;
console.log(results.key); // Logs: "data goes here"
});

如果你想在secStore.js中使用session storage或者cookies替代local storage,你可以在options中定义:

1
2
3
4
5
6
7
var options = {
encrypt: true,
storage: 'session', // or 'cookies'
data: {
key: 'data here'
}
};

localForage

这个库由Mozilla开发,给你提供一个简单的类localStorage API,但使用的是累死indexedDB 或 WebSQL等异步数据库。API十分像localStorage(getItem(), setItem(), 等), 除了它的API是异步的,并且参数要求传入callback。

举例来说,无论你设置还是获取数据,不会在return中获得任何值,但是你可以通过传入callback函数来处理数据,并且(可能的)处理错误。

1
2
3
4
5
6
7
8
9
10
11
localforage.setItem('key', 'value', function(err, value) {
console.log(value);
});
 
localforage.getItem('key', function(err, value) {
if (err) {
console.error('error message...');
} else {
console.log(value);
}
});

localForage其他要点:

  • 使用了JavaScript断言
  • 和其他库一样,并不只是存储字符串,也可以设置和获取对象
  • 允许你通过使用config()方法来设置数据库信息

Basil.js

Basil.js被描述为没有键值的localStorage, sessionStorage, 以及 cookie API,并且它包含了一些独特以及使用十分简单的功能。基本的方法可以参考以下:

1
2
3
4
5
6
basil = new Basil(options);
 
basil.set('foo', 'bar');
basil.get('foo');
basil.remove('foo');
basil.reset();

你也可以使用Basil.js来测试localStorage是否可用:

1
basil.check('local'); // returns Boolean value

Basil.js也允许你使用cookies或者sessionStorage:

1
2
3
4
5
6
7
basil.cookie.set(key, value, {
'expireDays': days, 'domain': 'mydomain.com'
});
basil.cookie.get(key);
 
basil.sessionStorage.set(key, value);
basil.sessionStorage.get(key);

最后,在options对象中,你可以使用options对象定义以下:

  • 命名空间或者你数据的不同部分
  • 存储方法的优先级排序
  • 默认存储方法
  • cookies过期时间
1
2
3
4
5
6
options = {
namespace: 'foo',
storages: ['cookie', 'local'],
storage: 'cookie',
expireDays: 31
};

lz-string

lz-string程序允许你使用压缩方式在localStorage中存储大量数据,并且它使用起来十分直接。在你页面中引用了这个库后,你可以做以下:

1
2
3
4
5
var string = 'A string to test our compression.';
console.log(string.length); // 33
var compressed = LZString.compress(string);
console.log(compressed.length); // 18
string = LZString.decompress(compressed);

注意到使用了compress()decompress()方法。上面代码中注释显示了在压缩前后的值的长度。你可以看见在客户端存储总是十分有限的情况下这方法是十分有效。

在库文档中的说明,可以选择使用Uint8Array(在JavaScript中的一种新型数据类型)压缩数据,并且可以在客户端外为storage压缩数据

Honorable Mentions

上面的工具可能帮助你做任何你想在localStorage中做的事情,但是如果你还在寻找更多的,这里会有一些更多的库你想看看。

  • LokiJS – 一个适用于node.js, browser, 以及 Cordova的快速,内存中,文档导向的数据存储。
  • AngularJS客户端数据存储 – Angular JS的命名空间数据存储写入localStorage,回调是cookie。和Angular core不一样,不依赖于其他外部依赖;不依赖ngCookies。
  • AlaSQL.js – JavaScript SQL 数据库,面向 browser和Node.js。处理传统关系类表和JSON数据(NoSQL)。从localStorage,IndexedDB或Excel中到处,存储和导入数据。
  • angular-locker 一个基于angular对象local/session storage简单的可配置的抽象,提供简单易用和流利的api。
  • jsCache – 允许通过localStorage缓存JavaScript 文件, CSS stylesheets以及数据。
  • LargeLocalStorage允许大量浏览器使用大key-value存储。

原文链接

此条目发表在研发分类目录,贴了, 标签。将固定链接加入收藏夹。

发表评论