更新程式碼

與其他問題無關的更新

這是三個說明部分的第一個部分,說明非擴充資料服務工作者一部分的程式碼所需的變更。本節適用於與其他問題無關的必要程式碼變更。接下來的兩個章節將說明封鎖網路要求提升安全性

將 tabs.executeScript() 替換為 scripting.executeScript()

在資訊清單 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']
});

在擴充功能服務 worker 中。

將 tabs.insertCSS() 和 tabs.removeCSS() 替換為 scripting.insertCSS() 和 scripting.removeCSS()

在資訊清單 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. 

在擴充功能服務 worker 中。

以 Actions 取代 Browser Actions 和 Page Actions

瀏覽器動作和網頁動作在 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"
  }

  ...
}

將 browserAction 和 pageAction API 替換為 action API

如果資訊清單 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 是代理程式或預留位置,用於非同步方法傳回的值。如果您從未使用過 Promise,可以前往 MDN 閱讀解答。本頁面說明在 Chrome 擴充功能中使用這些 API 時,您需要瞭解的相關資訊。

為了回溯相容性,許多方法在新增承諾支援後,仍會繼續支援回呼。請注意,您無法在同一個函式呼叫中同時使用這兩種方法。如果您傳遞回呼,函式就不會傳回承諾,如果您想要傳回承諾,請勿傳遞回呼。部分 API 功能 (例如事件監聽器) 仍需要回呼。如要確認方法是否支援 Promise,請在 API 參考資料中尋找「Promise」標籤。

如要從回呼轉換為承諾值,請移除回呼並處理傳回的承諾。以下範例取自選用權限範例,具體來說是 newtab.js。回呼版本會顯示樣本對 request() 的呼叫,以及回呼的樣子。請注意,承諾版本可以使用 async 和 await 重新編寫。

回撥電話
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 中變更。

資訊清單 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 時,請使用 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 (背景指令碼) 不支援擴充功能服務 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