更新代码

与其他问题无关的更新

本部分是对不属于扩展 Service Worker 的代码所需进行的更改的三个部分的第一部分。本部分针对的是与其他问题无关的代码更改必需更改。接下来的两部分将介绍取代阻塞 Web 请求提高安全性

将 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 不像 pageAction 那样提供 hide()show()。如果您仍需要执行页面操作,则可以使用声明式内容模拟此类操作,或使用标签页 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 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 => { ... });

将回调替换为 promise

在 Manifest V3 中,许多扩展 API 方法都会返回 promise。Promise 是异步方法所返回值的代理或占位符。如果您从未使用过 Promise,则可以在 MDN 上了解相关内容。本页介绍了在 Chrome 扩展程序中使用这些功能的须知事项。

为了实现向后兼容性,许多方法在添加 promise 支持后继续支持回调。请注意,您不能在同一个函数调用中同时使用这两者。如果您传递回调,则该函数不会返回 promise;如果您希望返回 promise,则不要传递回调。某些 API 功能(例如事件监听器)将继续要求使用回调。要检查某个方法是否支持 promise,请查找。

如需从回调转换为 promise,请移除回调并处理返回的 promise。以下示例取自可选权限示例(特别是 newtab.js)。回调版本显示了该示例使用回调对 request() 的调用是什么样的。请注意,可以使用 async 和 await 重写 promise 版本。

回拨电话
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()

您的扩展程序脚本应使用消息传递功能,以便在 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,请使用 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