更新程式碼

與其他問題無關的更新內容

本節是前三個部分,說明對非擴充功能 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 中。

將 tab.insertCSS() 和 tab.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() 的程序相同。

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 和 pageAction API 替換為動作 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 擴充功能中使用這些擴充功能的須知事項。

為顧及回溯相容性,許多方法在新增承諾支援後會繼續支援回呼。請注意,您無法在同一函式呼叫中同時使用兩者。如果您傳遞回呼,該函式不會傳回承諾,而如果您希望傳回的保證就不會傳遞回呼。部分 API 功能 (例如事件監聽器) 仍需回呼。如要確認方法是否支援承諾,請找到「Promise」標籤

如要從回呼轉換為承諾值,請移除回呼並處理傳回的承諾。以下範例來自選用權限範例,特別是 newtab.js。回呼版本會顯示對 request() 的範例使用回呼的呼叫方式。請注意,承諾版本可以使用 async 重新編寫並等待。

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

取代預期 Manifest V2 背景結構定義的函式

其他擴充功能內容只能透過訊息傳遞與擴充功能 Service Worker 互動。因此,您必須替換希望背景為背景的呼叫,具體來說:

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

擴充功能指令碼應使用訊息傳遞,在服務工作處理程序和擴充功能的其他部分之間通訊。目前可透過 sendMessage() 並在擴充功能 Service Worker 中實作 chrome.runtime.onMessage,完成這項操作。長期而言,您應該計劃將這些呼叫替換為 postMessage() 和服務工作處理程序的訊息事件處理常式

替換不支援的 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