擴充功能是 HTML、CSS、JavaScript、圖片和網路平台使用的其他檔案的壓縮組合,可自訂 Google Chrome 瀏覽體驗。擴充功能是使用網路技術建構而成,可使用瀏覽器為開放網路提供的相同 API。
擴充功能可實現各種功能,這類擴充功能可以修改使用者看到的網頁內容,以及與網頁內容互動的方式,也可以擴充及變更瀏覽器本身的行為。
擴充功能是打造個人化 Chrome 瀏覽器的入口。
擴充檔案
擴充功能包含的檔案類型和目錄數量不盡相同,但都必須具備 [資訊清單][docs-manifest]。有些實用但基本的擴充功能可能只包含資訊清單和工具列圖示。
名為 manifest.json 的資訊清單檔案會提供擴充功能相關資訊給瀏覽器,例如最重要的檔案,以及擴充功能可能使用的功能。
{
"name": "My Extension",
"version": "2.1",
"description": "Gets information from Google.",
"icons": {
"128": "icon_16.png",
"128": "icon_32.png",
"128": "icon_48.png",
"128": "icon_128.png"
},
"background": {
"persistent": false,
"scripts": ["background_script.js"]
},
"permissions": ["https://*.google.com/", "activeTab"],
"browser_action": {
"default_icon": "icon_16.png",
"default_popup": "popup.html"
}
}
擴充功能必須在瀏覽器工具列中顯示圖示。工具列圖示可讓使用者輕鬆存取擴充功能,並瞭解已安裝哪些擴充功能。大多數使用者會點選圖示,與使用彈出式視窗的擴充功能互動。
這項 Google Mail Checker 擴充功能使用瀏覽器動作:

這個 Mappy 擴充功能使用網頁動作和內容指令碼:

參照檔案
您可以使用相對網址參照擴充功能的檔案,就像一般 HTML 網頁中的檔案一樣。
<img src="images/my_image.png">
此外,您也可以使用絕對網址存取每個檔案。
chrome-extension://EXTENSION_ID/PATH_TO_FILE
在絕對網址中,EXTENSION_ID 是擴充功能系統為每個擴充功能產生的專屬 ID。如要查看所有已載入的擴充功能 ID,請前往 chrome://extensions。PATH_TO_FILE 是擴充功能頂層資料夾下的檔案位置,與相對網址相符。
處理未封裝的擴充功能時,擴充功能 ID 可能會變更。具體來說,如果從不同目錄載入未封裝的擴充功能,該擴充功能的 ID 就會變更;封裝擴充功能時,ID 會再次變更。如果擴充功能的程式碼依附於絕對網址,可以使用 chrome.runtime.getURL() 方法,避免在開發期間將 ID 硬式編碼。
架構
擴充功能的架構取決於其功能,但許多強大的擴充功能都會包含多個元件:
背景指令碼
背景指令碼是擴充功能的事件處理常式,內含擴充功能重要瀏覽器事件的監聽器。在事件觸發前,觸發條件會處於休眠狀態,觸發後則會執行指示的邏輯。有效背景指令碼只會在需要時載入,閒置時則會卸載。
UI 元素
擴充功能的使用者介面應簡潔明瞭,UI 應自訂或提升瀏覽體驗,但不得造成干擾。大多數擴充功能都有瀏覽器動作或網頁動作,但也可以包含其他形式的 UI,例如內容選單、使用網址列,或是建立鍵盤快速鍵。
擴充功能使用者介面頁面 (例如快顯視窗) 可以包含具有 JavaScript 邏輯的普通 HTML 頁面。擴充功能也可以呼叫 tabs.create 或 window.open(),顯示擴充功能中的其他 HTML 檔案。
如果擴充功能使用網頁動作和彈出式視窗,可以透過宣告式內容 API 在背景指令碼中設定規則,決定何時向使用者顯示彈出式視窗。符合條件時,背景指令碼會與彈出式視窗通訊,讓使用者可以點選圖示。

內容指令碼
讀取或寫入網頁的擴充功能會使用內容指令碼。內容指令碼包含 JavaScript,會在載入瀏覽器的網頁環境中執行。內容指令碼會讀取及修改瀏覽器造訪的網頁 DOM。

內容指令碼可以交換訊息,並使用 storage API 儲存值,與父項擴充功能通訊。

「選項」頁面
擴充功能可讓使用者自訂 Chrome 瀏覽器,而選項頁面則可讓使用者自訂擴充功能。選項可用於啟用功能,並允許使用者選擇符合自身需求的功能。
使用 Chrome API
除了與網頁存取相同的 API 之外,擴充功能還可以使用擴充功能專屬的 API,與瀏覽器緊密整合。擴充功能和網頁都可以存取標準 window.open() 方法來開啟網址,但擴充功能可以改用 Chrome API tabs.create 方法,指定要在哪個視窗中顯示網址。
非同步與同步方法
大多數 Chrome API 方法都是非同步的:這些方法會立即傳回,不會等待作業完成。如果擴充功能需要瞭解非同步作業的結果,可以將回呼函式傳遞至方法中。方法傳回後,回呼會在稍後執行,可能延遲很久。
如果擴充功能需要將使用者目前選取的索引標籤導向新網址,就必須取得目前索引標籤的 ID,然後將該索引標籤的地址更新為新網址。
如果 tabs.query 方法是同步,可能如下所示。
//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();
這個方法會失敗,因為 query() 是非同步。這個函式會立即傳回,不會等待工作完成,也不會傳回值。如果方法簽章中提供回呼參數,該方法就是非同步。
// Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)
如要正確查詢分頁並更新網址,擴充功能必須使用回呼參數。
//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();
在上述程式碼中,系統會依序執行第 1、4 和 2 行。系統會呼叫指定給 query() 的回呼函式,然後執行第 2 行,但前提是目前所選分頁的相關資訊必須可用。這項作業會在 query() 傳回後一段時間執行。雖然 update() 是非同步,但程式碼不會使用回呼參數,因為擴充功能不會對更新結果執行任何動作。
// Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()
這個方法會以同步方式傳回網址 (做為 string),且不會執行其他非同步作業。
瞭解詳情
如要瞭解詳情,請參閱 Chrome API 參考資料,並觀看下列影片。
網頁之間的通訊
擴充功能中的不同元件通常需要彼此通訊。不同 HTML 網頁可使用 chrome.extension 方法 (例如 getViews() 和 getBackgroundPage()) 互相尋找。如果某個頁面參照了其他擴充功能頁面,第一個頁面就能叫用其他頁面上的函式,並操控這些頁面的 DOM。此外,擴充功能的各個元件都能存取使用 storage API 儲存的值,並透過訊息傳遞進行通訊。
儲存資料和無痕模式
擴充功能可以透過 storage API、HTML5 web storage API 儲存資料,也可以發出伺服器要求,進而儲存資料。擴充功能需要儲存內容時,請先考量是否來自無痕視窗。根據預設,擴充功能不會在無痕視窗中執行。
無痕模式保證視窗不會留下任何足跡。處理無痕視窗的資料時,擴充功能應遵守這項承諾。如果擴充功能通常會儲存瀏覽記錄,請不要儲存無痕視窗的記錄。不過,擴充功能可以儲存任何視窗 (包括無痕視窗) 的設定偏好。
如要偵測視窗是否處於無痕模式,請檢查相關 tabs.Tab 或 windows.Window 物件的 incognito 屬性。
function saveTabData(tab) {
if (tab.incognito) {
return;
} else {
chrome.storage.local.set({data: tab.url});
}
}
後續行動
閱讀總覽並完成「開始使用」教學課程後,開發人員應該就能開始編寫自己的擴充功能!如要深入瞭解自訂 Chrome 的世界,請參閱下列資源。