朱德平
摘要:本文講述了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瀏覽器的功能和提高了用戶體驗。