與其他問題無關的更新
本節是三個章節中的第一個,說明擴充功能 Service Worker 以外的程式碼需要進行哪些變更。本節說明與其他問題無關,但必須進行的程式碼變更。接下來的兩個部分將說明如何取代封鎖網頁要求和提升安全性。
將 tabs.executeScript() 替換為 scripting.executeScript()
在 Manifest V3 中,executeScript() 會從 tabs API 移至 scripting API。除了實際變更程式碼外,您也必須變更資訊清單檔案中的權限。
executeScript() 方法需要:
"scripting"權限。- 主機權限或
"activeTab"權限。
scripting.executeScript() 方法與 tabs.executeScript() 的運作方式類似。兩者有幾項差異。
- 舊方法只能接受單一檔案,新方法則可接受檔案陣列。
- 您也需要傳遞
ScriptInjection物件,而非InjectDetails。兩者之間有多項差異。舉例來說,tabId現在會以ScriptInjection.target成員的形式傳遞,而非方法引數。
這個範例說明如何執行這項操作。
async function getCurrentTab() {/* ... */} let tab = await getCurrentTab(); browser.tabs.executeScript( tab.id, { file: 'content-script.js' } );
在背景指令碼檔案中。
async function getCurrentTab() let tab = await getCurrentTab(); browser.scripting.executeScript({ target: {tabId: tab.id}, files: ['content-script.js'] });
在擴充功能 Service Worker 中。
將 tabs.insertCSS() 和 tabs.removeCSS() 替換為 scripting.insertCSS() 和 scripting.removeCSS()
在 Manifest V3 中,insertCSS() 和 removeCSS() 會從 tabs API 移至 scripting API。除了變更程式碼外,您也必須變更資訊清單檔案中的權限:
"scripting"權限。- 主機權限或
"activeTab"權限。
scripting API 的函式與 tabs 的函式類似。兩者有幾項差異。
- 呼叫這些方法時,請傳遞
CSSInjection物件,而非InjectDetails。 tabId現在會以CSSInjection.target成員的形式傳遞,而非方法引數。
這個範例說明如何對 insertCSS() 執行這項操作。removeCSS() 的程序也相同。
browser.tabs.insertCSS(tabId, injectDetails, () => { // callback code });
在背景指令碼檔案中。
const insertPromise = await browser.scripting.insertCSS({ files: ["style.css"], target: { tabId: tab.id } }); // Remaining code.
在擴充功能 Service Worker 中。
以動作取代瀏覽器動作和網頁動作
在 Manifest V2 中,瀏覽器動作和網頁動作是不同的概念。雖然一開始兩者有明顯的角色區別,但隨著時間推移,兩者之間的差異逐漸縮小。在 Manifest V3 中,這些概念已整合至 Action API。這需要變更 manifest.json 和擴充功能程式碼,與您在 Manifest V2 背景指令碼中放入的程式碼不同。
Manifest V3 中的動作與瀏覽器動作最相似,但 action API 不會像 pageAction 一樣提供 hide() 和 show()。如果仍需要頁面動作,可以使用宣告式內容模擬,或使用分頁 ID 呼叫 enable() 或 disable()。
將「browser_action」和「page_action」替換為「action」
在 manifest.json 中,將 "browser_action" 和 "page_action" 欄位替換為 "action" 欄位。請參閱參考資料,瞭解 "action" 欄位。
{ ... "page_action": { ... }, "browser_action": { "default_popup": "popup.html" } ... }
{ ... "action": { "default_popup": "popup.html" } ... }
將 browserAction 和 pageAction API 替換為 action API
如果 Manifest V2 使用 browserAction 和 pageAction API,現在應改用 action API。
browser.browserAction.onClicked.addListener(tab => { ... }); browser.pageAction.onClicked.addListener(tab => { ... });
browser.action.onClicked.addListener(tab => { ... });
將回呼替換為 Promise
在 Manifest V3 中,許多擴充功能 API 方法會傳回 Promise。Promise 是非同步方法傳回值的 Proxy 或預留位置。如果您從未使用過 Promise,可以在 MDN 上參閱相關資訊。本頁面說明在 Chrome 擴充功能中使用這些 API 的須知事項。
為了回溯相容,許多方法在新增 Promise 支援後,仍會繼續支援回呼。請注意,您無法在同一個函式呼叫中同時使用這兩者。如果傳遞回呼,函式就不會傳回 Promise;如要傳回 Promise,請勿傳遞回呼。部分 API 功能 (例如事件監聽器) 仍需要回呼。如要確認方法是否支援 Promise,請在 API 參考資料中尋找「Promise」標籤。
如要將回呼轉換為 Promise,請移除回呼並處理傳回的 Promise。以下範例取自選用權限範例,特別是 newtab.js。回呼版本顯示範例對 request() 的呼叫在使用回呼時會是什麼樣子。請注意,Promise 版本可以使用 async 和 await 重寫。
browser.permissions.request(newPerms, (granted) => { if (granted) { console.log('granted'); } else { console.log('not granted'); } });
const newPerms = { permissions: ['topSites'] }; browser.permissions.request(newPerms) .then((granted) => { if (granted) { console.log('granted'); } else { console.log('not granted'); } });
取代預期 Manifest V2 背景情境的函式
其他擴充功能情境只能使用訊息傳遞與擴充功能 Service Worker 互動。因此,您需要取代預期背景內容的呼叫,具體來說:
browser.runtime.getBackgroundPage()browser.extension.getBackgroundPage()browser.extension.getExtensionTabs()
擴充功能指令碼應使用訊息傳遞,在 Service Worker 和擴充功能的其他部分之間進行通訊。目前,您可以透過 sendMessage() 達成這項操作,並在擴充功能 Service Worker 中實作 browser.runtime.onMessage。長期而言,您應規劃將這些呼叫替換為 postMessage() 和 Service Worker 的訊息事件處理常式。
替換不支援的 API
下列方法和屬性必須在 Manifest V3 中變更。
| Manifest V2 方法或屬性 | 替換成 |
|---|---|
browser.extension.connect() |
browser.runtime.connect() |
browser.extension.connectNative() |
browser.runtime.connectNative() |
browser.extension.getExtensionTabs() |
browser.extension.getViews() |
browser.extension.getURL() |
browser.runtime.getURL() |
browser.extension.lastError |
如果方法傳回 Promise,請使用 promise.catch() |
browser.extension.onConnect |
browser.runtime.onConnect |
browser.extension.onConnectExternal |
browser.runtime.onConnectExternal |
browser.extension.onMessage |
browser.runtime.onMessage |
browser.extension.onRequest |
browser.runtime.onMessage |
browser.extension.onRequestExternal |
browser.runtime.onMessageExternal |
browser.extension.sendMessage() |
browser.runtime.sendMessage() |
browser.extension.sendNativeMessage() |
browser.runtime.sendNativeMessage() |
browser.extension.sendRequest() |
browser.runtime.sendMessage() |
browser.runtime.onSuspend (背景指令碼) |
不支援擴充功能 Service Worker。請改用 beforeunload 文件事件。 |
browser.tabs.getAllInWindow() |
browser.tabs.query() |
browser.tabs.getSelected() |
browser.tabs.query() |
browser.tabs.onActiveChanged |
browser.tabs.onActivated |
browser.tabs.onHighlightChanged |
browser.tabs.onHighlighted |
browser.tabs.onSelectionChanged |
browser.tabs.onActivated |
browser.tabs.sendRequest() |
browser.runtime.sendMessage() |
browser.tabs.Tab.selected |
browser.tabs.Tab.highlighted |