chrome.tabs 呼叫的方式和其他程式碼沒有兩樣。它真正改變的,是你在開發期間實際執行的那份 manifest,而這個差異裡藏著一個陷阱。
開發期會注入 tabs 權限
開發循環重新載入 content script 的方式,是把它們注入到已經開啟的分頁裡。這需要你的擴充功能可能沒有宣告的權限,所以 Extension.js 會把它們加進寫入dist/ 的那份 manifest。
對於 manifest v3 專案,開發期會在 permissions 中加上:
host_permissions。
對於 manifest v2 專案,開發期加的是 tabs 與 storage,再加上那些 match 樣式,因為 manifest v2 沒有 host_permissions 這個鍵。
這些都不會進到正式環境。extension build 輸出的,剛好就是你宣告過的那些權限。
這個差異你可以自己看到。在 manifest.json 中只宣告 storage,然後比較兩次建置:
dist/chromium/manifest.json
dist/chromium/manifest.json
這個陷阱,以及如何避開
因為開發期注入了tabs,即使 manifest.json 從未申請過這個權限,chrome.tabs.query 在 extension dev 中依然會成功。同一個呼叫在 extension build 之後就會失敗。
對某些 API,Extension.js 會為此發出警告。用了 chrome.management 卻沒有宣告它,建置就會告訴你:
storage、scripting 與 management。它不涵蓋 tabs。 一個呼叫 chrome.tabs 卻沒宣告權限的專案,編譯乾淨、開發期執行乾淨,然後在打包後的擴充功能裡壞掉。
用了什麼就宣告什麼:
manifest.json
dist/chromium 以未封裝擴充功能的方式載入,再把功能實際跑一遍。
你真的需要 tabs 權限嗎?
很多擴充功能並不需要。tabs 權限的存在是為了讀取受保護的欄位,而不是為了呼叫這個 API。
activeTab 是比較小的請求。它授予的是使用者操作過的那個分頁的存取權,有效期就是那一次造訪。商店審核它的態度,比 tabs 加 <all_urls> 寬厚得多。
完整清單請閱讀權限與主機權限。
跨瀏覽器命名
Firefox 與 Safari 提供以 Promise 為基礎的browser.tabs。Chromium 提供以 callback 為基礎的 chrome.tabs。Extension.js 透過 webextension-polyfill 在 Chromium 上提供 browser 命名空間,因此一種寫法到處都能用:
從終端機指定單一分頁
有幾個 CLI 動詞作用於單一分頁。先列出開啟中的分頁:--tab 只接受數字形式的分頁 id,其他都不行。若想改用網址來比對,請用 --url,它接受一個 match 樣式或一段單純的子字串:
reload 上,--tab 選的是動作對象。在 logs 上,它過濾的是已經記錄下來的事件。
extension storage 沒有 --tab 選項。請改用 --context 選擇介面。
失敗訊息
最後一條在
chrome:// 頁面與 Web Store 上很常見,任何擴充功能都碰不得那些頁面。
最佳實務
- 要讀取分頁 URL 時就宣告
tabs。開發期不會提醒你。 - 當工作由使用者手勢啟動時,優先選用
activeTab。 - 對著正式建置驗證權限,而不是開發建置。
- 永遠不要假設分頁 id 能撐過瀏覽器重新啟動。請重新查詢一次。
後續步驟
- 回顧權限與主機權限。
- 用 eval 指令從終端機驅動瀏覽器。
- 閱讀 content script 的相關說明。

