CHROME扩展开发之·迁移到 Manifest V3

迁移到 Manifest V3

让你朝着正确的方向前进。

发表于 2020 年 11 月 9 日,星期一 •更新于2021 年 8 月 13 日,星期五

目录
  • 功能概要
  • 更新 manifest.json 文件
    • 清单版本
    • 主机权限
    • 内容安全政策
    • 动作API统一
    • 可通过网络访问的资源
  • 代码执行
    • 远程托管代码
    • 执行任意字符串
  • 后台服务人员
  • 修改网络请求
    • 什么时候可以使用阻塞 webRequest?
    • 你如何使用 declarativeNetRequest ?
    • 条件权限和 declarativeNetRequest
  • 已弃用 API 的日落

本指南为开发人员提供了开始将扩展从 Manifest V2 迁移到 Manifest V3 (MV3) 所需的信息。一些扩展只需要很少的改动就可以使它们符合 MV3,而另一些扩展则需要在一定程度上重新设计。具有 MV2 经验以及正在创建新的 MV3 扩展的开发人员也可能会发现这很有帮助。有关快速参考指南,请参阅迁移清单。

Manifest V3 提供了许多反映我们平台愿景目标的改进。

# 功能概要

使用 MV3 的扩展有许多新特性和功能更改:

  • 服务工作者替换背景页面。
  • 现在使用新的declarativeNetRequest API处理网络请求修改。
  • 不再允许远程托管代码;扩展只能执行包含在其包中的 JavaScript。
  • Promise支持已添加到许多方法中,但仍支持回调作为替代方案。(我们最终将支持对所有适当方法的承诺。)
  • MV3 中还引入了许多其他相对较小的功能更改。

有关这些更改的更完整说明,请参阅MV3 概述。

# 更新 manifest.json 文件

要使用 MV3 的功能,您需要先更新您的清单文件。自然地,您将清单版本更改为“3”,但您需要在清单文件中更改许多其他内容:主机权限、内容安全策略、操作声明和 Web 可访问资源。

# 清单版本

更改 manifest_version 元素的值是升级扩展的关键。这决定了您使用的是 MV2 还是 MV3 功能集:

// Manifest V2

"manifest_version": 2
// Manifest V3

"manifest_version": 3

# 主机权限

在 MV3 中,您需要将主机权限与其他权限分开指定:

// Manifest V2
"permissions": [
"tabs",
"bookmarks",
"http://www.blogger.com/",
],
"optional_permissions": [
"*://*/*",
"unlimitedStorage"
]
// Manifest V3
"permissions": [
"tabs",
"bookmarks"
],
"optional_permissions": [
"unlimitedStorage"
],
"host_permissions": [
"http://www.blogger.com/",
"*://*/*"
],
警告

您不必host_permissions为了注入内容脚本而声明内容脚本匹配模式。然而,他们视为通过Chrome Web Store的审查过程中主机的权限请求。

# 内容安全政策

MV2 中将扩展的内容安全策略(CSP) 指定为字符串;在 MV3 中,它是一个对象,其成员代表替代 CSP 上下文:

// Manifest V2

"content_security_policy": "..."
// Manifest V3

"content_security_policy": {
"extension_pages": "...",
"sandbox": "..."
}

extension_pages:此政策涵盖您的扩展程序中的页面,包括 html 文件和 Service Worker。

这些页面类型由chrome-extension://协议提供。例如,扩展程序中的一个页面是chrome-extension:///foo.html.

sandbox:此政策涵盖您的扩展程序使用的任何沙盒扩展程序页面。

此外,MV3 不允许对extension_pagesMV2 中允许的某些 CSP 修改进行修改。的script-src, object-src,并且worker-src指示只能有以下值:

  • self
  • none
  • 任何本地主机源、( http://localhosthttp://127.0.0.1或这些域上的任何端口)

CSP 修改sandbox没有这样的新限制。

# 动作API统一

在 MV2 中,有两种不同的 API 来实现操作:browser_actionpage_action. 这些 API 在引入时扮演了不同的角色,但随着时间的推移,它们变得多余,因此在 MV3 中我们将它们统一为单个actionAPI:

// Manifest V2

// manifest.json
{
"browser_action": {},
"page_action": {}
}

// background.js
chrome.browserAction.onClicked.addListener(tab => {});
chrome.pageAction.onClicked.addListener(tab => {});
// Manifest V3

// manifest.json
{
"action": {}
}


// background.js
chrome.action.onClicked.addListener(tab => {});

# 可通过网络访问的资源

此更改将扩展资源的访问权限限制为特定站点/扩展。您现在提供了一个对象列表,而不是提供文件列表,每个对象都可以将一组资源映射到一组 URL 或扩展 ID:

// Manifest V2

"web_accessible_resources": [

]
// Manifest V3

"web_accessible_resources": [{
"resources": [],
"matches": [],
"extension_ids": [],
optional "use_dynamic_url": boolean
}]

以前,Web 可访问资源列表适用于所有网站和扩展程序,这为指纹识别或无意的资源访问创造了机会。更新后的 API 允许扩展更严格地控​​制哪些其他站点或扩展可以访问扩展资源。有关使用信息,请参阅Web 可访问资源文档。

# 代码执行

MV3 施加了新的限制,通过平台更改和策略限制的组合来限制扩展执行未经审查的 JavaScript 的能力。

许多扩展不受此更改的影响。但是,如果您的 MV2 扩展执行远程托管脚本、将代码字符串注入页面或在运行时评估字符串,则您需要在迁移到 MV3 时更新代码执行策略。

使用 Manifest V3,该executeScript()方法也移动到不同的 API。

  • MV2:  chrome.tabs.executeScript()
  • MV3: chrome.scripting.executeScript()。

如果您在代码中的任何位置使用 executeScript(),则需要更新该调用以使用新 API。该insertCSS()removeCSS()方法类似地从chrome.tabs移到chrome.scripting。

# 远程托管代码

远程托管代码是指任何未作为可加载资源包含在扩展包中的代码。例如,以下两种代码都被视为远程托管代码:

  • 从远程服务器拉取的 JavaScript 文件
  • 在运行时传递给 eval 的代码字符串

在 MV3 中,所有扩展的逻辑都必须与扩展捆绑在一起。您不能再加载和执行远程托管的文件。有多种替代方法可用,具体取决于您的用例和远程托管的原因。两种这样的方法是:

配置驱动的特性和逻辑——在这种方法中,你的扩展在运行时加载远程配置(例如 JSON 文件)并在本地缓存配置。然后,扩展程序使用此缓存配置来决定要启用哪些功能。

使用远程服务外部化逻辑——考虑将应用程序逻辑从扩展程序迁移到您的扩展程序可以调用的远程 Web 服务。(本质上是一种消息传递形式。)这使您能够将代码保密并按需更改代码,同时避免重新提交到 Chrome 网上应用店的额外开销。

# 执行任意字符串

在 Manifest V2 中,可以使用选项对象上的tabs.executeScriptcode属性执行任意代码字符串。Manifest V3 不允许执行任意代码。为了适应这种需求,扩展开发者可以使用scripting.executeScriptAPI 来注入静态文件或函数。

静态文件注入scripting.executeScript几乎与 Tabs API 中使用的相同。旧方法只需要一个文件,而新方法现在需要一个文件数组。

// Manifest V2

// background.js
chrome.tabs.executeScript({
file: 'content-script.js'
});

// content-script.js
alert('File test alert');
// Manifest V3

// background.js
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

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

// content-script.js
alert('File test alert');

如果您需要更多动态,新func属性允许您将函数作为内容脚本注入并使用该args属性传递变量。请注意,该函数不会像位于内容脚本中那样运行;相反,它的源被发送到目标选项卡并在那里运行。

// Manifest V2

// background.js
let name = 'World!';
chrome.tabs.executeScript({
code: `alert('Hello, ${name}!')`
});
// Manifest V3

// background.js
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

function showAlert(givenName) {
alert(`Hello, ${givenName}`);
}

let name = 'World';
chrome.scripting.executeScript({
target: {tabId: tab.id},
func: showAlert,
args: [name],
});

可以在chrome-extensions-samples存储库中找到本节中 Manifest V3 片段的功能版本。请参阅Tabs API 示例以了解getCurrentTab.

# 后台服务人员

MV2 中的后台页面被 MV3 中的 Service Worker 替换:这是影响大多数扩展的基础性更改。

Service Worker是基于事件的,并且与事件页面一样,它们不会在调用之间持续存在。此更改通常需要进行一些重新设计,需要考虑许多因素:有关其他详细信息,请参阅从后台页面迁移到 Service Workers。

为了帮助迁移过程,从 Chrome 87 开始,MV2 扩展可以使用后台服务工作者。

# 修改网络请求

有一个新的declarativeNetRequest用于网络请求修改,它为webRequest AP 的大部分功能提供了替代方案。

# 什么时候可以使用阻塞 webRequest?

webRequest API的阻塞版本仍然存在于 MV3 中,但它的使用仅限于强制安装的扩展。请参阅 Chrome 企业政策:ExtensionSettings、ExtensionInstallForcelist。

所有其他扩展现在必须使用declarativeNetRequest进行网络请求修改。这将网络请求的实际修改移到 Chrome 浏览器中:扩展程序不再能够读取实际的网络请求,并且在大多数情况下不需要主机权限。

请求重定向和标头修改确实需要用户授予主机权限。

# 你如何使用 declarativeNetRequest ?

您的扩展不是读取请求并以编程方式更改它,而是指定了许多规则,这些规则将一组条件映射到相应的操作。有关规则的更详细说明,请参阅declarativeNetRequest参考文档。

此功能允许内容拦截器和其他请求修改扩展程序在不需要主机权限的情况下实现它们的用例,也不需要读取实际请求。

为了帮助迁移过程,从 Chrome 84 开始,declarativeNetRequest API 可用于 MV2 扩展。

# 条件权限和 declarativeNetRequest

declarativeNetRequest 的大多数用例根本不需要任何主机权限。然而,有些人这样做。

请求重定向和标头修改确实需要用户授予主机权限。

当扩展需要这些用例的主机权限时,我们建议使用“分层”权限策略。这意味着在不使用这些权限的情况下实现扩展的核心功能;将更高级的用例置于可选权限之后。

这种方法允许注重隐私的用户保留这些权限,并仍然使用扩展程序的大部分功能。这意味着开发人员可以实现许多常见用例,例如内容阻止功能,而无需任何主机权限。

# 已弃用 API 的日落

有许多 API 早已被弃用。Manifest V3 最终取消了对这些已弃用 API 的支持。这些包括:

  • chrome.extension.sendRequest()
  • chrome.extension.onRequest
  • chrome.extension.onRequestExternal
  • chrome.extension.lastError
  • chrome.extension.getURL()
  • chrome.extension.getExtensionTabs()
  • chrome.tabs.Tab.selected
  • chrome.tabs.sendRequest()
  • chrome.tabs.getSelected()
  • chrome.tabs.getAllInWindow()
  • chrome.tabs.onSelectionChanged
  • chrome.tabs.onActiveChanged
  • chrome.tabs.onHighlightChanged

以及未记录的:

  • chrome.extension.sendMessage()
  • chrome.extension.connect()
  • chrome.extension.onConnect
  • chrome.extension.onMessage

如果您的扩展使用这些已弃用的 API 中的任何一个,则在迁移到 MV3 时需要进行适当的更改。

最近更新时间: 2021 年 8 月 13 日,星期五 改进文章

你可能感兴趣的:(chrome,前端)