chrome作為目前最流行的瀏覽器,備受前端推崇,原因除了其對於前端標準的支援這一大核心原因之外,還有就是其強大的擴充套件性。
基於其開發規範實現的外掛如今已經非常龐大,在國內也是欣欣向榮,如天貓開發了大量的擴充套件,用於檢測頁面質量以及頁面效能,淘寶開發了許多的擴充套件以供運營工具的優化等等。其強大性不言而喻。
這裡我們來講一下其外掛開發
基礎概念
與chrome應用類似,chrome擴充套件主要是用於擴充chrome瀏覽器的功能。他體現為一些檔案的集合,包括前端檔案(html/css/js),配置檔案manifest.json。
主要採用JavaScript語言進行編寫。個別擴充套件可能會用到DLL和so動態庫,不過出於安全以及職責分離的考慮,在後續的標準中,將會被捨棄,這裡不再贅述
chrome擴充套件能做的事情:
- 基於瀏覽器本身視窗的互動介面
- 操作使用者頁面:操作使用者頁面裡的dom
- 管理瀏覽器:書籤,cookie,歷史,擴充套件和應用本身的管理,其中甚至修改chrome的一些預設頁面,位址列關鍵字等,包括瀏覽器外觀主題都是可以更改的
這裡需要著重提一下,前端開發者喜歡的DevTools工具,在這裡也能進行自定義
- 網路通訊:http,socket,UDP/TCP等
- 跨域請求不受限制
- 常駐後臺執行
- 資料儲存:採用3種方式(localStorage,Web SQL DB,chrome提供的儲存API(檔案系統))
- 擴充套件頁面間可進行通訊:提供runtime相關介面
- 其他功能:下載,代理,系統資訊,媒體庫,硬體相關(如usb裝置操作,串列埠通訊等),國際化
chrome擴充套件的限制:
環境限制:基本上功能性操作都需要通過chrome提供的API來完成,這跟實際的頁面js又有一些差異,看上去並沒有那麼的完全自由。
如chrome擴充套件的頁面指令碼,可以獲取並操作頁面dom,但是,出於安全性的考慮,頁面指令碼的域是獨立區分開來的,即js成員變數不共享。
即:插入到使用者頁面的js指令碼可執行,但是與原始指令碼不同執行域,互相不會影響。
content_script不能使用除了chrome.extension之外的chrome.*的介面,不能訪問它所在擴充套件中定義的函式和變數,不能訪問web頁面或其它content script中定義的函式和變數,不能做cross-site XMLHttpRequests
chrome擴充套件,其功能受限於chrome的API,比如說檔案系統,必須通過chrome的fileSystem介面,而這些介面僅僅只是對html5已有的檔案系統介面的擴充套件,它允許Chrome應用讀寫硬碟中使用者選擇的任意位置,而HTML5本身提供的檔案系統介面則只能在沙箱中讀寫檔案,並不能獲取使用者磁碟中真正的目錄。
舉個例子
下面以一個簡單的例子來簡述一下我們開發擴充套件過程中會遇到哪些問題
這個栗子主要用於去自定義使用者頁面的樣式(比如此處為改滾動條樣式),插入一個自定義的指令碼到使用者頁面中執行(此處為輸出一些簡單資訊)
【1】編輯擴充套件程式所需要的主要資料夾
檔案結構說明
./
├─ manifest.json //擴充套件的配置項
├─ Custom.js //自定義js指令碼
├─ Custom.css //自定義css樣式
├─ icon.png //擴充套件程式的icon
└─ popup.html //擴充套件的展示彈窗複製程式碼
自定義js指令碼:瀏覽器中執行,但並非真正意義上的“插入”,與原來頁面的js域隔離開
例如,custom.js中的window跟頁面js中的window不是同一個物件,變數也無法共享。
console.log('執行init'); console.log(document.title); console.log(document.getElementById("abc")); // 例項函式,可以供popup.html中呼叫 function helloWorld(name){ console.log(`${name} say 'hello world!'`); alert(`${name} say 'hello world!'`); } //...複製程式碼
這樣的指令碼路徑將以 chrome://extensions/擴充套件的id串碼/path/to/you/js/xxx.js出現在控制檯除錯時候。
- 自定義樣式:同樣,css也不是真正的插入到頁面的document中,而是瀏覽器的樣式生效策略中會加入這些樣式規則
/* 重置滾動條 */
::-webkit-scrollbar {width:4px!important;height:7px;}
::-webkit-scrollbar-button {display:none;}
::-webkit-scrollbar-thumb {border-radius:3px;background: #45A5DB;}
::-webkit-scrollbar-track {width:4px;height:7px;background:transparent;}
::-webkit-scrollbar-track-piece {background:transparent;}
/* ... */複製程式碼
- 小視窗popup.html:這裡面是一個按鈕,點選後去呼叫custom.js裡面的helloWorld函式
<!doctype html>
<html>
<head>
<title>hello world</title>
</head>
<body>
<h2>hello world</h2>
<p><button onclick="dealClick('王小明')">按鈕</button></p>
<script>
function dealClick(name){
//這裡值得注意,大部分功能性操作,比如執行指令碼,執行函式,都是不可以直接執行,而需要通過chrome.*這樣方式進行
chrome.tabs.executeScript(
null,
{
code: `helloWorld('${name}')` // 這裡呼叫的是上面的custom.js重定義好的function
}
);
}
</script>
</body>
</html>複製程式碼
- 核心配置檔案manifest.json:
{
"name": "副檔名稱",
"version": "1.0.0",
"manifest_version": 2,
"description": "擴充套件描述",
"icons" : { // 擴充套件的icon
"16" : "icon.png",
"48" : "icon.png",
"128" : "icon.png"
},
"browser_action": { // browser_action表示程式圖示會出現在位址列右側,若要出現在位址列,則寫成page_action
"default_title": "日報工具",
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts": [ //content_scripts是在Web頁面內執行的javascript指令碼。
//通過使用標準的DOM,它們可以獲取瀏覽器所訪問頁面的詳細資訊,並可以修改這些資訊。
{ //這裡的值是陣列,可以針對多個站點進行不同的操作配置
"matches": [
"http://www.google.com/*"
],
"css": [
"custom.css"
],
"js": [
"custom.js"
],
"all_frames": true,
"run_at": "document_idle"
}
],
"permissions": [ //一些許可權的配置,
"cookies", //比如cookie許可權,比如系統通知許可權,類似於notify這樣的東西,在window系統上未右下角的小氣泡
"notifications"
]
}複製程式碼
page_action,browser_action型別的擴充套件對應位置
【2】打包生成外掛包
- 瀏覽器開啟 chrome://extensions/(或者‘更過工具->擴充套件程式’),左上角有一個
打包擴充套件程式
按鈕
- 然後,將生成的*.crx檔案拖到瀏覽器即可完成安裝。
到這步外掛其實已經差不多了,當然,這裡的功能都比較簡單,你可以自己嘗試一些更高階的功能
由於自己DIY的擴充套件是沒有釋出到web app store的,所以下次開啟瀏覽器時會被禁掉,解決方法見第二篇文章《chrome外掛開發簡介(二)——如何添“加瀏覽器擴充套件白名單”》