朱德平
摘要:本文讲述了Firefox浏览器扩展开发的原理,包括扩展API、后台脚本与内容脚本、用户界面、配置、权限与管理等内容。并讲解了扩展开发的部分主要代码范例。
关键词:扩展;开发;基本原理;Firefox;浏览器
中图分类号:TP311 文献标识码:A 文章编号:1007-9416(2018)08-0121-01
浏览器扩展的用途是为浏览器添加特性和功能。按用途大致分为三类:一是对浏览器本身的补充和增强。例如翻译、广告移除、网页剪切和批注、开发和调试辅助等。二是为某一个或一类网站提供附加的服务。例如购物比价、视音频地址解析及下载等。三是基于扩展的独立应用。例如待办事项和时间管理、网页小游戏等。本文首先讲述Firefox扩展开发的基本原理和部分主要代码范例。
1 基本原理
Firefox扩展开发基于常规的HTML、CSS和JavaScript技术,和开发网页所用的技术相同,另外添加了一组专用于扩展开发的技术特性,下面分别论述。
1.1 扩展API
Firefox为扩展提供了一组扩展API(WebExtensions API),作为扩展的运行时API,目前包含40余个功能模块,每个模块包含若干函数、属性、事件和类型,提供一类功能。具体包括访问和操纵浏览器的菜单、书签、剪切板、下载、历史、代理、cookies、本地存储功能;浏览器用户界面与扩展的绑定;权限和安全管理;扩展内部脚本、不同扩展、扩展与本地应用程序之间的通信;扩展安装、移除管理等。所有的扩展API都放在browser名字空间下,每个子模块在browser下又有自己的名字空间。扩展API中有许多异步函数,是基于Promise异步机制。WebExtensions API是跨浏览器的API,因此为Firefox开发的插件只需要进行少量修改,就可以在Google Chrome和Microsoft Edge中运行。
1.2 后台脚本和内容脚本
Firefox扩展由JavaScript代码以及附加的HTML、CSS等文件组成,JavaScript代码主要有后台脚本(background scripts)和内容脚本(content script)两种。后台脚本运行在独立的进程内,当扩展启动时,后台脚本开始运行,首先执行扩展初始化、事件绑定等操作,随后进入事件处理循环,当接受到停止运行事件时,脚本结束执行。后台脚本可以使用所有的扩展API以及JavaScript语言规范内置的函数、对象等。但是后台脚本不能对浏览器当前显示的网页进行操作,内容脚本可以像网页脚本(网站网页自带的JavaScript代码)一样嵌入到网页上下文中,利用标准的DOM API操纵网页元素。 需要注意内容脚本只能看到一个“干净的网页DOM视图”,意思一是内容脚本不能查看网页脚本定义的JavaScript变量;二是如果网页脚本重新定义了一个内置DOM属性,内容脚本无法看到重新定义的属性,只能看到原始的属性,这种特性称作“Xray vision”,是为了使高特权级代码可以安全的访问由低特权级代码创建的对象。内容脚本和后台脚本可以通过消息机制进行通信,互相传输数据。内容脚本只能直接使用扩展API的一个小的子集,但可以通过消息机制间接的使用其他的扩展API。
1.3 用户界面
扩展可以通过向浏览器添加按钮或者利用面板和网页创建自定义界面的形式和用户进行交互,具体共有11种形式,例如浏览器工具条按钮、地址栏按钮、侧边栏面板、上下文菜单项、选项页面等。扩展展示给用户的面板和页面由HTML、CSS和JavaScript,在JavaScript中可以调用扩展API。
1.4 配置
每个扩展必须包含一个名字为manifest.json的配置文件,对扩展的各项功能进行集中装配和配置,包括30余个配置参数,例如指定扩展调用的后台脚本和内容脚本文件、组成用户界面的HTML文件、按钮等的图标文件、键盘快捷键、权限管理以及扩展的名称、作者、版本信息等。
1.5 权限管理
通过manifest.json中的permissions参数可以为扩展指定各类权限。权限分为下面几种,一是主机权限,用于指定扩展通过XML Http Request不受跨域限制可以访问的URL资源以及其它与URL资源访问相关的权限。二是API权限,用于指定可以在当前扩展中使用的扩展API。三是activeTab权限,用于指定当用户与扩展交互式,是否能以编程的方式动态将JavaScript和CSS注入当前活动选项卡中的网页以及能否访问选项卡的Tab.url,Tab.title和Tab.faviconUrl属性。另外还可以设置剪切板和存储权限。
2 代码范例
下面列举部分开发中常用操作的代码范例。
2.1 Manifest.json主要配置
配置内容脚本,当用户页面访问百度网站时,脚本content.js嵌入当前页面执行。
"content_scripts": [
{ "matches": ["https://www.baidu.com/*"], "js": ["content.js"] }]
配置后臺脚本,当扩展启动时,运行background.js代码。
"background": {
"scripts": ["background.js"] }
在地址栏中添加扩展按钮。
" page_action ": {
"default_icon": { "16": "icon 16.png", "32": "icon32.png" }
2.2 拦截浏览器发往百度网站的所有Http请求,由预先定义的handle函数处理
browser.webRequest.onBeforeRequest.addListener(
handle, {urls: ["https://www.baidu.com/"]} ) }
2.3 内容脚本和后台脚本的通信
内容脚本中将数据data发往后台脚本。
var port = browser.runtime.connect({name:""});
port.postMessage(data);
2.4 后台脚本接受数据
后台脚本监听内容脚本的连接事件,当连接成功后,监听内容脚本的消息到达事件,处理接受到的消息。
function connected(port) {
port.onMessage.addListener(function(data) {
console.log(data);
});}
browser.runtime.onConnect.addListener(connected);
3 结语
Firefox浏览器提供了强大的扩展API,使得用户可以增加和修改浏览器功能,同时相比XUL/XPCOM、Add-on SDK等以前的扩展方式简化了编程,又和其它主流浏览器扩展相兼容,极大的增强了Firefox浏览器的功能和提高了用户体验。