朱德平
摘要:本文講述了Firefox瀏覽器擴(kuò)展開(kāi)發(fā)的原理,包括擴(kuò)展API、后臺(tái)腳本與內(nèi)容腳本、用戶界面、配置、權(quán)限與管理等內(nèi)容。并講解了擴(kuò)展開(kāi)發(fā)的部分主要代碼范例。
關(guān)鍵詞:擴(kuò)展;開(kāi)發(fā);基本原理;Firefox;瀏覽器
中圖分類(lèi)號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1007-9416(2018)08-0121-01
瀏覽器擴(kuò)展的用途是為瀏覽器添加特性和功能。按用途大致分為三類(lèi):一是對(duì)瀏覽器本身的補(bǔ)充和增強(qiáng)。例如翻譯、廣告移除、網(wǎng)頁(yè)剪切和批注、開(kāi)發(fā)和調(diào)試輔助等。二是為某一個(gè)或一類(lèi)網(wǎng)站提供附加的服務(wù)。例如購(gòu)物比價(jià)、視音頻地址解析及下載等。三是基于擴(kuò)展的獨(dú)立應(yīng)用。例如待辦事項(xiàng)和時(shí)間管理、網(wǎng)頁(yè)小游戲等。本文首先講述Firefox擴(kuò)展開(kāi)發(fā)的基本原理和部分主要代碼范例。
1 基本原理
Firefox擴(kuò)展開(kāi)發(fā)基于常規(guī)的HTML、CSS和JavaScript技術(shù),和開(kāi)發(fā)網(wǎng)頁(yè)所用的技術(shù)相同,另外添加了一組專(zhuān)用于擴(kuò)展開(kāi)發(fā)的技術(shù)特性,下面分別論述。
1.1 擴(kuò)展API
Firefox為擴(kuò)展提供了一組擴(kuò)展API(WebExtensions API),作為擴(kuò)展的運(yùn)行時(shí)API,目前包含40余個(gè)功能模塊,每個(gè)模塊包含若干函數(shù)、屬性、事件和類(lèi)型,提供一類(lèi)功能。具體包括訪問(wèn)和操縱瀏覽器的菜單、書(shū)簽、剪切板、下載、歷史、代理、cookies、本地存儲(chǔ)功能;瀏覽器用戶界面與擴(kuò)展的綁定;權(quán)限和安全管理;擴(kuò)展內(nèi)部腳本、不同擴(kuò)展、擴(kuò)展與本地應(yīng)用程序之間的通信;擴(kuò)展安裝、移除管理等。所有的擴(kuò)展API都放在browser名字空間下,每個(gè)子模塊在browser下又有自己的名字空間。擴(kuò)展API中有許多異步函數(shù),是基于Promise異步機(jī)制。WebExtensions API是跨瀏覽器的API,因此為Firefox開(kāi)發(fā)的插件只需要進(jìn)行少量修改,就可以在Google Chrome和Microsoft Edge中運(yùn)行。
1.2 后臺(tái)腳本和內(nèi)容腳本
Firefox擴(kuò)展由JavaScript代碼以及附加的HTML、CSS等文件組成,JavaScript代碼主要有后臺(tái)腳本(background scripts)和內(nèi)容腳本(content script)兩種。后臺(tái)腳本運(yùn)行在獨(dú)立的進(jìn)程內(nèi),當(dāng)擴(kuò)展啟動(dòng)時(shí),后臺(tái)腳本開(kāi)始運(yùn)行,首先執(zhí)行擴(kuò)展初始化、事件綁定等操作,隨后進(jìn)入事件處理循環(huán),當(dāng)接受到停止運(yùn)行事件時(shí),腳本結(jié)束執(zhí)行。后臺(tái)腳本可以使用所有的擴(kuò)展API以及JavaScript語(yǔ)言規(guī)范內(nèi)置的函數(shù)、對(duì)象等。但是后臺(tái)腳本不能對(duì)瀏覽器當(dāng)前顯示的網(wǎng)頁(yè)進(jìn)行操作,內(nèi)容腳本可以像網(wǎng)頁(yè)腳本(網(wǎng)站網(wǎng)頁(yè)自帶的JavaScript代碼)一樣嵌入到網(wǎng)頁(yè)上下文中,利用標(biāo)準(zhǔn)的DOM API操縱網(wǎng)頁(yè)元素。 需要注意內(nèi)容腳本只能看到一個(gè)“干凈的網(wǎng)頁(yè)DOM視圖”,意思一是內(nèi)容腳本不能查看網(wǎng)頁(yè)腳本定義的JavaScript變量;二是如果網(wǎng)頁(yè)腳本重新定義了一個(gè)內(nèi)置DOM屬性,內(nèi)容腳本無(wú)法看到重新定義的屬性,只能看到原始的屬性,這種特性稱(chēng)作“Xray vision”,是為了使高特權(quán)級(jí)代碼可以安全的訪問(wèn)由低特權(quán)級(jí)代碼創(chuàng)建的對(duì)象。內(nèi)容腳本和后臺(tái)腳本可以通過(guò)消息機(jī)制進(jìn)行通信,互相傳輸數(shù)據(jù)。內(nèi)容腳本只能直接使用擴(kuò)展API的一個(gè)小的子集,但可以通過(guò)消息機(jī)制間接的使用其他的擴(kuò)展API。
1.3 用戶界面
擴(kuò)展可以通過(guò)向?yàn)g覽器添加按鈕或者利用面板和網(wǎng)頁(yè)創(chuàng)建自定義界面的形式和用戶進(jìn)行交互,具體共有11種形式,例如瀏覽器工具條按鈕、地址欄按鈕、側(cè)邊欄面板、上下文菜單項(xiàng)、選項(xiàng)頁(yè)面等。擴(kuò)展展示給用戶的面板和頁(yè)面由HTML、CSS和JavaScript,在JavaScript中可以調(diào)用擴(kuò)展API。
1.4 配置
每個(gè)擴(kuò)展必須包含一個(gè)名字為manifest.json的配置文件,對(duì)擴(kuò)展的各項(xiàng)功能進(jìn)行集中裝配和配置,包括30余個(gè)配置參數(shù),例如指定擴(kuò)展調(diào)用的后臺(tái)腳本和內(nèi)容腳本文件、組成用戶界面的HTML文件、按鈕等的圖標(biāo)文件、鍵盤(pán)快捷鍵、權(quán)限管理以及擴(kuò)展的名稱(chēng)、作者、版本信息等。
1.5 權(quán)限管理
通過(guò)manifest.json中的permissions參數(shù)可以為擴(kuò)展指定各類(lèi)權(quán)限。權(quán)限分為下面幾種,一是主機(jī)權(quán)限,用于指定擴(kuò)展通過(guò)XML Http Request不受跨域限制可以訪問(wèn)的URL資源以及其它與URL資源訪問(wèn)相關(guān)的權(quán)限。二是API權(quán)限,用于指定可以在當(dāng)前擴(kuò)展中使用的擴(kuò)展API。三是activeTab權(quán)限,用于指定當(dāng)用戶與擴(kuò)展交互式,是否能以編程的方式動(dòng)態(tài)將JavaScript和CSS注入當(dāng)前活動(dòng)選項(xiàng)卡中的網(wǎng)頁(yè)以及能否訪問(wèn)選項(xiàng)卡的Tab.url,Tab.title和Tab.faviconUrl屬性。另外還可以設(shè)置剪切板和存儲(chǔ)權(quán)限。
2 代碼范例
下面列舉部分開(kāi)發(fā)中常用操作的代碼范例。
2.1 Manifest.json主要配置
配置內(nèi)容腳本,當(dāng)用戶頁(yè)面訪問(wèn)百度網(wǎng)站時(shí),腳本content.js嵌入當(dāng)前頁(yè)面執(zhí)行。
"content_scripts": [
{ "matches": ["https://www.baidu.com/*"], "js": ["content.js"] }]
配置后臺(tái)腳本,當(dāng)擴(kuò)展啟動(dòng)時(shí),運(yùn)行background.js代碼。
"background": {
"scripts": ["background.js"] }
在地址欄中添加擴(kuò)展按鈕。
" page_action ": {
"default_icon": { "16": "icon 16.png", "32": "icon32.png" }
2.2 攔截瀏覽器發(fā)往百度網(wǎng)站的所有Http請(qǐng)求,由預(yù)先定義的handle函數(shù)處理
browser.webRequest.onBeforeRequest.addListener(
handle, {urls: ["https://www.baidu.com/"]} ) }
2.3 內(nèi)容腳本和后臺(tái)腳本的通信
內(nèi)容腳本中將數(shù)據(jù)data發(fā)往后臺(tái)腳本。
var port = browser.runtime.connect({name:""});
port.postMessage(data);
2.4 后臺(tái)腳本接受數(shù)據(jù)
后臺(tái)腳本監(jiān)聽(tīng)內(nèi)容腳本的連接事件,當(dāng)連接成功后,監(jiān)聽(tīng)內(nèi)容腳本的消息到達(dá)事件,處理接受到的消息。
function connected(port) {
port.onMessage.addListener(function(data) {
console.log(data);
});}
browser.runtime.onConnect.addListener(connected);
3 結(jié)語(yǔ)
Firefox瀏覽器提供了強(qiáng)大的擴(kuò)展API,使得用戶可以增加和修改瀏覽器功能,同時(shí)相比XUL/XPCOM、Add-on SDK等以前的擴(kuò)展方式簡(jiǎn)化了編程,又和其它主流瀏覽器擴(kuò)展相兼容,極大的增強(qiáng)了Firefox瀏覽器的功能和提高了用戶體驗(yàn)。