更新程式碼

與其他問題無關的更新

針對不屬於擴充功能 Service Worker 的程式碼,說明需要進行哪些變更,這是前三節的說明。本節適用於與其他問題無關的程式碼變更。接下來兩節將說明如何取代封鎖網路要求改善安全性

將 tab.executeScript() 替換為 Scripting.executeScript()

在 Manifest V3 中,executeScript()tabs API 移至 scripting API。如要這麼做,除了實際的程式碼變更外,您也必須變更資訊清單檔案中的權限。

對於 executeScript() 方法,您需要:

  • "scripting" 權限。
  • 主機權限或 "activeTab" 權限。

scripting.executeScript() 方法類似於搭配 tabs.executeScript() 的運作方式。但有以下幾項差異。

  • 雖然舊方法只能擷取單一檔案,但新方法可以使用多個檔案。
  • 此外,您也可以傳遞 ScriptInjection 物件,而非 InjectDetails。兩者之間有多項差異。舉例來說,tabId 現在會以 ScriptInjection.target 成員的形式傳遞,而非做為方法引數。

範例說明如何執行這項操作。

Manifest V2
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

chrome.tabs.executeScript(
  tab.id,
  {
    file: 'content-script.js'
  }
);

在背景指令碼檔案中。

Manifest V3
async function getCurrentTab()
let tab = await getCurrentTab();

chrome.scripting.executeScript({
  target: {tabId: tab.id},
  files: ['content-script.js']
});

擴充功能 Service Worker。

以 Scripting.insertCSS() 和 Scripting.removeCSS() 取代 tab.insertCSS() 和 tab.removeCSS()

在 Manifest V3 中,insertCSS()removeCSS() 已從 tabs API 移至 scripting API。這需要變更資訊清單檔案中的權限,除了程式碼變更之外:

  • "scripting" 權限。
  • 主機權限或 "activeTab" 權限。

scripting API 上的函式與 tabs 上的函式類似。但有以下幾項差異。

  • 呼叫這些方法時,您必須傳遞 CSSInjection 物件,而不是 InjectDetails
  • tabId 現在會做為 CSSInjection.target 的成員傳遞,而非方法引數。

範例說明如何為 insertCSS() 執行這項操作。removeCSS() 的程序相同。

Manifest V2
chrome.tabs.insertCSS(tabId, injectDetails, () => {
  // callback code
});

在背景指令碼檔案中。

Manifest V3
const insertPromise = await chrome.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 並不會提供 hide()show()pageAction 相同。如果您仍需要使用網頁動作,可以使用宣告式內容模擬這些動作,或者使用分頁 ID 呼叫 enable()disable()

將「browser_action」和「page_action」替換為「action」

manifest.json 中,將 "browser_action""page_action" 欄位替換為 "action" 欄位。請參閱 "action" 欄位資訊的參考。

Manifest V2
{
  ...
  "page_action": { ... },
  "browser_action": {
    "default_popup": "popup.html"
   }
  ...
}
Manifest V3
{
  ...
  "action": {
    "default_popup": "popup.html"
  }

  ...
}

使用動作 API 取代瀏覽器動作 API 和 pageAction API

如果您的 Manifest V2 使用 browserActionpageAction API,現在應使用 action API。

Manifest V2
chrome.browserAction.onClicked.addListener(tab => { ... });
chrome.pageAction.onClicked.addListener(tab => { ... });
Manifest V3
chrome.action.onClicked.addListener(tab => { ... });

將回呼替換為承諾項目

在 Manifest V3 中,許多擴充功能 API 方法會傳回承諾。Promise 是代表非同步方法傳回值的 Proxy 或預留位置。如果您從未使用過 Promise,可以前往 MDN 參閱相關資訊。本頁說明在 Chrome 擴充功能中使用須知的須知事項。

為了提供回溯相容性,許多方法在新增 promise 支援後,會繼續支援回呼。請注意,您無法在同一個函式呼叫中同時使用這兩種方法。如果您傳遞回呼,函式將不會傳回 promise,而且如果您希望傳回的 promise 不會通過回呼,某些 API 功能 (例如事件監聽器) 仍需要回呼。如要檢查方法是否支援承諾,請在其 API 參考資料中尋找「Promise」標籤。

如要將回呼轉換為 promise,請移除回呼並處理傳回的承諾。以下範例來自選用權限範例,特別是 newtab.js。回呼版本會顯示使用回呼的範例,呼叫 request() 時看起來會是什麼樣子。請注意,我們能以非同步方式重新編寫 promise 版本,並等待。

回撥電話
chrome.permissions.request(newPerms, (granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});
保證
const newPerms = { permissions: ['topSites'] };
chrome.permissions.request(newPerms)
.then((granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});

替換需要 Manifest V2 背景內容的函式

其他擴充功能內容只能使用訊息傳遞與擴充功能服務工作站互動。因此,您必須替換預期背景結構定義的呼叫,具體而言如下:

  • chrome.runtime.getBackgroundPage()
  • chrome.extension.getBackgroundPage()
  • chrome.extension.getExtensionTabs()

您的擴充功能指令碼應使用訊息傳遞,在 Service Worker 和擴充功能的其他部分之間進行通訊。目前,您需要在擴充功能 Service Worker 中使用 sendMessage() 和實作 chrome.runtime.onMessage。長期而言,您應該將這些呼叫替換為 postMessage() 以及 Service Worker 的訊息事件處理常式

替換不支援的 API

下列方法與屬性必須在 Manifest V3 中變更。

Manifest V2 方法或屬性 取代為
chrome.extension.connect() chrome.runtime.connect()
chrome.extension.connectNative() chrome.runtime.connectNative()
chrome.extension.getExtensionTabs() chrome.extension.getViews()
chrome.extension.getURL() chrome.runtime.getURL()
chrome.extension.lastError 在方法傳回承諾的位置,請使用 promise.catch()
chrome.extension.onConnect chrome.runtime.onConnect
chrome.extension.onConnectExternal chrome.runtime.onConnectExternal
chrome.extension.onMessage chrome.runtime.onMessage
chrome.extension.onRequest chrome.runtime.onMessage
chrome.extension.onRequestExternal chrome.runtime.onMessageExternal
chrome.extension.sendMessage() chrome.runtime.sendMessage()
chrome.extension.sendNativeMessage() chrome.runtime.sendNativeMessage()
chrome.extension.sendRequest() chrome.runtime.sendMessage()
chrome.runtime.onSuspend (背景指令碼) 不適用於擴充功能 Service Worker。請改用 beforeunload 文件事件。
chrome.tabs.getAllInWindow() chrome.tabs.query()
chrome.tabs.getSelected() chrome.tabs.query()
chrome.tabs.onActiveChanged chrome.tabs.onActivated
chrome.tabs.onHighlightChanged chrome.tabs.onHighlighted
chrome.tabs.onSelectionChanged chrome.tabs.onActivated
chrome.tabs.sendRequest() chrome.runtime.sendMessage()
chrome.tabs.Tab.selected chrome.tabs.Tab.highlighted