2.6 储存数据
一个程序免不了要储存数据,对于Chrome扩展也是这样。通常Chrome扩展使用以下三种方法中的一种来储存数据:第一种是使用HTML5的localStorage
,这种方法在上一节的内容中已经涉及;第二种是使用Chrome提供的存储API;第三种是使用Web SQL Database。
对于一般的扩展,“设置”这种简单的数据可以优先选择第一种,因为这种方法使用简单,可以看成是特殊的JavaScript变量;对于结构稍微复杂一些的数据可以优先选择第二种,这种方法可以保存任意类型的数据,但需要异步调用Chrome的API,结果需要使用回调函数接收,不如第一种操作简单;第三种目前使用的不算太多,因为需要使用SQL语句对数据库进行读写操作,较前两者更加复杂,但是对于数据量庞大的应用来说是个不错的选择。开发者应根据实际的情况选择上述三种方法中的一种或几种来存储扩展中的数据。
由于上节已经讲解了localStorage
的使用方法,下面将详细讲解后两种储存数据的方法。
Chrome存储API
Chrome为扩展应用提供了存储API,以便将扩展中需要保存的数据写入本地磁盘。Chrome提供的存储API可以说是对localStorage
的改进,它与localStorage
相比有以下区别:
如果储存区域指定为
sync
,数据可以自动同步;content_scripts
可以直接读取数据,而不必通过background页面;在隐身模式下仍然可以读出之前存储的数据;
读写速度更快;
用户数据可以以对象的类型保存。
对于第二点要进一步说明一下。首先localStorage
是基于域名的,这在前面的小节中已经提到过了。而content_scripts
是注入到用户当前浏览页面中的,如果content_scripts
直接读取localStorage
,所读取到的数据是用户当前浏览页面所在域中的。所以通常的解决办法是content_scripts
通过runtime.sendMessage
和background通信,由background读写扩展所在域(通常是chrome-extension://extension-id/)的localStorage
,然后再传递给content_scripts
。
使用Chrome存储API必须要在Manifest的permissions
中声明"storage"
,之后才有权限调用。Chrome存储API提供了2种储存区域,分别是sync
和local
。两种储存区域的区别在于,sync
储存的区域会根据用户当前在Chrome上登陆的Google账户自动同步数据,当无可用网络连接可用时,sync
区域对数据的读写和local区域对数据的读写行为一致。
对于每种储存区域,Chrome又提供了5个方法,分别是get
、getBytesInUse
、set
、remove
和clear
。
get
方法即为读取数据,完整的方法为:
chrome.storage.StorageArea.get(keys, function(result){
console.log(result);
});
keys
可以是字符串、包含多个字符串的数组或对象。如果keys
是字符串,则和localStorage
的用法类似;如果是数组,则相当于一次读取了多个数据;如果keys
是对象,则会先读取以这个对象属性名为键值的数据,如果这个数据不存在则返回keys
对象的属性值(比如keys
为{'name':'Billy'}
,如果name
这个值存在,就返回name
原有的值,如果不存在就返回Billy
)。如果keys
为一个空数组([]
)或空对象({}
),则返回一个空列表,如果keys
为null
,则返回所有存储的数据。
getBytesInUse
方法为获取一个数据或多个数据所占用的总空间,返回结果的单位是字节,完整方法为:
chrome.storage.StorageArea.getBytesInUse(keys, function(bytes){
console.log(bytes);
});
此处的keys
只能为null
、字符串或包含多个字符串的数组。
set
方法为写入数据,完整方法为:
chrome.storage.StorageArea.set(items, function(){
//do something
});
items
为对象类型,形式为键/值对。items
的属性值如果是字符型、数字型和数组型,则储存的格式不会改变,但如果是对象型和函数型的,会被储存为“{}
”,如果是日期型和正则型的,会被储存为它们的字符串形式。
remove
方法为删除数据,完整方法为:
chrome.storage.StorageArea.remove(keys, function(){
//do something
});
其中keys
可以是字符串,也可以是包含多个字符串的数组。
clear
方法为删除所有数据,完整方法为:
chrome.storage.StorageArea.clear(function(){
//do something
});
请注意,上述五种完整方法中,StorageArea
必须指定为local
或sync
中的一个。
Chrome同时还为存储API提供了一个onChanged
事件,当存储区的数据发生改变时,这个事件会被激发。
onChanged
的完整方法为:
chrome.storage.onChanged.addListener(function(changes, areaName){
console.log('Value in '+areaName+' has been changed:');
console.log(changes);
});
callback
会接收到两个参数,第一个为changes
,第二个是StorageArea
。changes
是词典对象,键为更改的属性名称,值包含两个属性,分别为oldValue
和newValue
;StorageArea
为local
或sync
。
Web SQL Database
Web SQL Database的三个核心方法为openDatabase
、transaction
和executeSql
。openDatabase
方法的作用是与数据库建立连接,transaction
方法的作用是执行查询,executeSql
方法的作用是执行SQL语句。
下面举一个简单的例子:
db = openDatabase("db_name", "0.1", "This is a test db.", 1024*1024);
if(!db){
alert('数据库连接失败。');
}
else {
db.transaction( function(tx) {
tx.executeSql(
"SELECT COUNT(*) FROM db_name",
[],
function(tx, result){
console.log(result);
},
function(tx, error){
alert('查询失败:'+error.message);
}
);
}
}
更多关于Web SQL Database的资料可以参考http://www.w3.org/TR/webdatabase/。由于原生的Web SQL Database并不算好用,也有一些开源的二次封装的库来简化Web SQL Database的使用,如https://github.com/KenCorbettJr/html5sql。
以上几种数据的存储方式都不会对数据加密,如果储存的是敏感的数据,应该先进行加密处理。比如不要将用户密码的明码直接储存,而应先进行MD5加密。