Chrome 为扩展应用提供了存储 API,以便将扩展中需要保存的数据写入本地磁盘。Chrome 提供的存储 API 可以说是对
localStorage
的改进,它与
localStorage
相比有以下区别:
用户数据可以通过 Chrome 浏览器的同步功能自动同步(使用
storage.sync
)
content_scripts
可以直接读取数据,而不必通过
background
页面
在隐身模式下仍然可以读出之前存储的数据
读写速度更快
用户数据可以以对象的类型保存(
localStorage
API 以字符串方式存储数据)。
对于第二点要进一步说明一下。首先
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
。
在
sync
区域存储和读取数据:
chrome.storage.sync.set({key: value}, function() {
console.log('Value is set to ' + value);
chrome.storage.sync.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
local
区域:
chrome.storage.local.set({key: value}, function() {
console.log('Value is set to ' + value);
chrome.storage.local.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
// 从存储中读取数据
chrome.storage.sync.get('user1', function(result) {
document.write('name: ' + result['user1'].name + '<br>' + 'age: ' + result['user1'].age );
现在我们能在页面上看到刚存储的数据:
在 get()
方法中 keys
可以是字符串、包含多个字符串的数组或对象。
如果 keys
是字符串,则和 localStorage
的用法类似(见上例);如果是数组,则相当于一次读取了多个数据。
var user1 = {'name': 'diego', 'age': 18}
var user2 = {'name': 'tony', 'age': 19}
// 往存储中写入数据
chrome.storage.sync.set({'user2': user2}, function() {
console.log('保存成功');
chrome.storage.sync.set({'user1': user1}, function() {
console.log('保存成功');
// 从存储中读取数据
chrome.storage.sync.get(['user1', 'user2'], function(result) {
document.write(
'name: ' + result['user1'].name + '<br>' + 'age: ' + result['user1'].age
+ '<hr>'
+ 'name: ' + result['user2'].name + '<br>' + 'age: ' + result['user2'].age
如果 keys
是对象,则会先读取以这个对象属性名为键值的数据,如果这个数据不存在则返回 keys
对象的属性值(比如 keys
为 {'name':'Billy'}
,如果 name
这个值存在,就返回 name
原有的值,如果不存在就返回 'Billy'
)。
var user1 = {'name': 'diego', 'age': 18}
var default_user = {'name': 'default_user', 'age': 18}
// 往存储中写入数据
chrome.storage.sync.set({'user1': user1}, function() {
console.log('保存成功');
// 从存储中读取数据
chrome.storage.sync.get({'user2': default_user}, function(result) {
document.write('name: ' + result['user2'].name + '<br>' + 'age: ' + result['user2'].age );
因为 'user2'
这个值是不存在的,所以返回的是 default_user
这个对象;如果换成 'user1'
这个存在的值,则会返回 user1
这个对象。
如果 keys
为一个空数组([]
)或空对象({}
),则返回一个空列表,如果 keys
为 null
,则返回所有存储的数据。
getBytesInUse()
方法为获取一个数据或多个数据所占用的总空间,返回结果的单位是字节,完整方法为:
// sync 区域
chrome.storage.sync.getBytesInUse(keys, function(bytes){
console.log(bytes);
// local 区域
chrome.storage.local.getBytesInUse(keys, function(bytes){
console.log(bytes);
此处的 keys
只能为 null
、字符串或包含多个字符串的数组。
set()
方法为写入数据,完整方法为:
// sync 区域
chrome.storage.sync.set(items, function(){
//do something
// local 区域
chrome.storage.local.set(items, function(){
//do something
items
为对象类型,形式为键/值对。items
的属性值如果是字符型、数字型和数组型,则储存的格式不会改变,但如果是对象型和函数型的,会被储存为 "{}"
,如果是日期型和正则型的,会被储存为它们的字符串形式。
remove()
方法为删除数据,完整方法为:
// sync 区域
chrome.storage.sync.remove(keys, function(){
//do something
// local 区域
chrome.storage.local.remove(keys, function(){
//do something
其中 keys
可以是字符串,也可以是包含多个字符串的数组。
clear()
方法为删除所有数据,完整方法为:
// sync 区域
chrome.storage.sync.clear(function(){
//do something
// local 区域
chrome.storage.local.clear(function(){
//do something
Chrome 同时还为存储 API 提供了一个 onChanged()
事件,当存储区的数据发生改变时,这个事件会被激发。
onChanged()
的完整方法为:
chrome.storage.onChanged.addListener(function(changes, areaName){