Chrome扩展开发02--扩展中的基本操作02

533 阅读5分钟
原文链接: zhuanlan.zhihu.com

1、带选项页面的扩展

有一些扩展允许用户进行一些个性化的设置,此时就需要提供一个“选项”页面。

Chrome通过manifest.json文件中的options_page属性为开发者提供这样的接口。例如在《Chrome扩展与应用开发》中,作者以“天气预报”扩展为例,允许用户在“选项”页面中设置地点,以显示该地点天气。

(1)在manifest.json文件中添加:

(2)编写options.html文件:

这里涉及到一个选项存储问题。对于网站来说,用户的设置一般存储在cookie中,或者保存在网站的数据库中。在这里,我们使用到了HTML5新增的localStorage接口,该接口允许我们在用户的计算机中永久的存储数据(除非被主动删除)。使用方法如下:

》localStorage.city = .... 或者 localStorage['city'] = ... 用于读取或者设置选项
》localStorage.removeItem('city')用于删除设置选项

但该接口本身也有一些限制:

》localStorage和Cookie类似,都有域的限制,不允许跨域调用。
》localStorage存储数据的大小有限制,对于Chrome而言,最大存储为5M。
》localStorage只能存储字符串类型的数据,不能存储其他对象。

除了localStorage存储数据的方法之外,还有其他方法,下边会提到。

(3)编写options.js文件:

(4)编写popup.html和weather.js。前者用于展示天气,后者用于获取指定城市的天气。这里就不再一一赘述,可参考作者源代码:chrome_extensions_and_apps_programming

最后的一个效果为:


2、扩展页面间的通讯

有时候扩展中的多个页面之间,或者扩展与扩展之间,需要进行相互通讯,以获取彼此的状态。比如UI界面点击某歌曲,需要通知后台页面播放,后台页面播放完成之后,也需要UI页面进行相应展示。

Chrome提供了4个相关的接口:

runtime.sendMessage
runtime.onMessage
runtime.connect
runtime.onConnect

注意:Chrome提供的大部分API接口是不支持在content_scripts中运行的,但是runtime.sendMessage和runtime.onMessage是特例,所以扩展页面也可以与content_scripts之间相互通信。

runtime.sendMessage的完整方法为:

chrome.runtime.sendMessage(extensionId, message, options, callback)
# extensionId为所发送消息的目标扩展,如果不指定,则为该扩展本身
# message为所发送的消息,可以为任意类型的内容
# options为一个可选参数,这里可以先忽略
# callback为回调函数,用于接受返回结构。同样是一个可选参数

runtime.onMessage的完整方法为:

chrome.runtime.onMessage.addListener(callback)
# callback为回调函数,接受3个参数:message、sender和sendResponse

举个例子,前端页面发送消息给后台页面,同时显示后台页面返回的消息。

popup.html中发送消息,并显示返回的消息:

后台页面接受消息,并返回消息:

3、扩展中存储数据

在扩展程序中保存数据是在所难免的,比如我们前边提到的保存用户设置选项。在Chrome中,有3中方法用于存储数据。

(1)使用HTML5中的localStorage接口。这个在前边已经介绍过了。

(2)使用Chrome提供的存储API接口。

(3)使用Web SQL Database。

对于一般的扩展程序,一些简单的存储优先选择第一种存储方法,因为它比较简单,可以直接看成特殊的JS变量。对于一些稍微复杂的数据结构,可以考虑第二种存储方法,它的优点就是可以存储任意类型的变量。第三种存储方法一般很少使用到。

这里主要介绍第二种存储方法。Chrome的存储API接口可以看做是对localStorage的改进:

(1)如果存储区域指定为sync,数据可以自动同步;

(2)content_scripts可以直接读取数据,而不必通过background页面;

(3)在隐身模式下仍然可以读出之前存储的数据;

(4)读写速度更快;

(5)用户数据可以以对象的类型保存。

对于第二点,简单说明下。由于localStorage有域的限制,而content_scripts为注入到其他页面中的脚本,所以如果content_scripts直接读取localStorage,读取的是当前浏览页面的存储,不是扩展的。有个解决办法是通过sendMessage发送到后台页面,做个中转。

使用Chrome的存储API需要在manifest文件中声明“storage”,以获取相应权限。Chrome存储API提供了两种存储区域:local和sync。两者的区别是后者可以利用Google账户进行同步。

对于每一种存储区域,Chrome提供了5个方法:get / getBytesInUse / set / remove / clear。

chrome.storage.StorageArea.get(keys, function(result){
    console.log(result);
})  # 读取数据
# keys可以为字符串、包括多个字符串的数组或对象。如果keys为null则返回所有数据
chrome.storage.StorageArea.getBytesInUse(keys, function(bytes){
   console.log(bytes);
})  # 读取字节数据
chrome.storage.StorageArea.set(items, function(){
   console.log();
})  # 设置数据,items为键值对
chrome.storage.StorageArea.remove(keys, function(){
})  # 删除数据
chrome.storage.StorageArea.clear(function(){
})  # 清除所有数据

除了上述5个方法外,Chrome的存储API还提供了一个onChange事件,用于监听存储区域的数据变化。使用方法为:

chrome.storage.onChange.addListener(function(changes, areaName){
  console.log('Value in ' + areaName + ' has been changed!');
  console.log(changes)
})

这里顺带提一句Web SQL Database:

4、i18n的使用

使用i18n接口实现扩展应用程序的国际化!有需要了解的可自行百度。

=============================================================

作者主页:笑虎(Python爱好者,关注爬虫、数据分析、数据挖掘、数据可视化等)

作者专栏主页:撸代码,学知识 - 知乎专栏

作者GitHub主页:撸代码,学知识 - GitHub

欢迎大家拍砖、提意见。相互交流,共同进步!

==============================================================