Chrome浏览器扩展插件教程:从MV2迁移到Manifest V3

扫描二维码

Chrome Web Store于2021年1月已经开始接受Manifest V3扩展的提交。如果你还在使用MV2版本,那么一定要在官方弃用之前,尽快更新到MV3版本。

Chrome浏览器从88版本开始支持MV3啦(即Manifest Version 3),目前查看官方文档时默认已经是MV3版本。

我们这篇文章主要了解3个问题

1、MV2的弃用时间表

2、了解MV3的新特性

3、如何将MV2迁移到MV3

一、Manifest V2弃用时间表

此图表指定了弃用Manifest V2(MV2)的时间表

Untitled

  • 2022年1月份开始不接受新的MV2版本(除了”私人”可见类型),开发者可以更新已经存在的MV2扩展插件
  • 2022年6月份不接受新的MV2版本,开发者可以更新已经存在的MV2扩展插件
  • 2023年1月份开始,开发者不能更新MV2的扩展插件,MV2也不能在Chrome浏览器运行(除了个别的企业版)
  • 2023年6月份MV2版本将不能在Chrome浏览器运行

二、Manifest V3新特性

Manifest V3是十年前推出扩展平台以来最大的转变之一。Manifest V3的新的扩展规范将在安全性、私密性和性能方面得到增强;也可以使用Manifest V3中采用的更现代的开放网络技术,比如Service Worker和Promises。并会逐步淘汰Manifest V2。

MV3新特性概要

  • Service worker替换Background Page
  • 网络请求修改使用新的 declarativentrequest API 来处理。
  • 不再允许执行远程托管的代码;只能执行扩展包内包含的JavaScript。
  • Promises 已经被添加到许多方法中,目前回调仍然支持作为一种替代方法。(最终将支持所有Promises)
  • Action API整合:Browser Action API 和Page Action APIs被统一为一个单独的Action API。
  • Web可访问的资源:资源只对指定的站点和扩展可用。
  • 内容安全策略(CSP):现在可以为单个对象中的不同执行上下文指定单独的CSP,并且某些特定的策略是不被允许的。
  • executeScript的变化:扩展不能再执行任意字符串,只能执行脚本文件和函数。这种方法也从Tabs API迁移到新的Scripting API。

三、如何将MV2迁移到MV3

1、修改manifest.json

1)manifest.json版本号

显而易见第一步需求修改 manifest.json 文件

{
    ...,
    "manifest_version": 3,
    ...
}

2)Host Permissions

在Manifest V2中,有两种方法为你的api或任何主机获得权限,要么在 permissions 数组或 optional_permissions 数组。

在Manifest V3中,所有主机权限现在都单独存在一个新数组中,该数组的键为 host_permissions。主机权限不再与其他权限一起添加。

MV2

{
    ...,
    "permissions": [
        "https://tahub.app/*"
      ],
    ...
}

MV3

{
    ...,
    "host_permissions": [
        "https://tahub.app/*"
      ],
    ...
}

3)Background Scripts

Manifest V3用Service Worker替换了 background scripts。

MV2 Background对象目前看起来是这样的:

{
    ...,
    "background": {
        "scripts": ["assets/js/background.js"],
        "persistent": false
      },
    ...
}

我们需要做的是把 script 数组的键改为 service_worker,替换多个background pages或scripts。所以,它应该是这样的:

{
    ...,
    "background": {
        "service_worker": "assets/js/background.js"
      },
    ...
}

注意,我们不再需要添加 persistent了。

4)Actions

Actions 过去是 browser_actionpage_action,但现在它们在Manifest V3中统一为 Actions 。这是因为随着时间的推移,分开他们变得没有必要。

MV2

// Manifest V2

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

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

MV3

// Manifest V3

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

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

5)Content Security Policy (CSP)

你需要改变它从一个String(在Manifest V2)到一个Object(在Manifest v3)。

MV2

// Manifest V2

"content_security_policy": "..."

MV3

// Manifest V3

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

6)Web-Accessible Resources

web_accessible_resources 数组更改为一个详细描述所有资源的对象,每个对象都可以映射到到一组url或扩展id。下面是V3版本的一个例子:

MV2

// Manifest V2

"web_accessible_resources": [
  RESOURCE_PATHS
]

MV3

// Manifest V3

"web_accessible_resources": [{
  "resources": [RESOURCE_PATHS]
}]

此外还支持其它的属性,用于设定不同的规则: matchesextension_idsuse_dynamic_url

2、将 Background Scripts 改造成 Service Workers

首先,什么是service worker,它和background scripts有什么不同?

background scripts在几乎所有扩展中都是必不可少的。允许执行一些操作或执行代码,而不需要用户打开某个页面或执行某些操作。这可以用于发送通知、与content scripts通信等等。后台脚本通常总是在后台运行。

Service worker在需要的时候被执行。与后台脚本不同,它们并不总是在后台运行。在最顶层,service worker将监听器注册到一些事件中,以允许它们稍后被执行。

从background scripts到service worker的转换依赖于扩展中的代码。一些扩展可能需要大量的工作,而另一些则不需要这么多。

需要做的第一步是将以前作为background scripts文件移动到根目录。

{
    ...,
    "background": {
        "service_worker": "background.js"
      },
    ...
}

现在,让我们看看代码。以前的background script如下:

chrome.runtime.onMessage.addListener(function(message, sender, senderResponse){
  if(message.msg === "image"){
    fetch('https://some-random-api.com/img/xxx')
          .then(response => response.text())
          .then(data => {
            let dataObj = JSON.parse(data);
            senderResponse({data: dataObj, index: message.index});
          })
          .catch(error => console.log("error", error))
      return true; 
  }
});

基本上,我们的后台脚本使用 chrome.runtime.onMessage.addListener 来监听一个消息,如果该消息请求一个图片,它将向API发送一个请求,然后将数据返回给我们的content script。

这个background script实际上不需要任何额外的更改。因为service worker的后台脚本只是注册了一个事件监听器,并在事件发生时执行代码,这正是service worker应该做的。

但并不是所有的扩展都是这样的,因为有不同的情况。以下是你在background script中需要检查和修改的内容:

1) 全局变量

以前的后台脚本总是在后台运行。如果有以下代码:

let count = 0;

chrome.runtime.onMessage.addListener( (message) => {
    count++;
    console.log(count);
});

每当service worker收到一条消息时,count就会增加。一开始是0,然后是1,然后是2,以此类推。

在service worker中,这将不再有效。service worker只会在需要时运行,并在完成工作时终止。因此,上述代码将始终在控制台打印“1”。

在上面的例子中,计数可以在background script和content script之间来回传递,以获得所需的结果。更好的方法是使用Chrome的存储API。

2) Timers and Alarms

Timers在后台脚本中使用没有问题,因为它们总是在后台运行。然而,这不适用于服务工作者。你应该用 Alarms API 替换所有的计时器。

3) 访问DOM

Service worker不能访问windows或DOM。如果你的扩展需要,你可以使用类似 jsdom 的库或使用chrome.windows.create和chrome.tabs.create。这取决于你的具体使用场景。

如果你的background scripts有录制音频或视频,这也是需要修改的,因为这在service worker中是不可以的。

4) 创建Canvas

如果你的background scripts之前创建了画布,你仍然可以用 offscreenenccanvas API 来做。你所要做的就是用 OffscreenCanvas 替换 document

MV2

let canvas = document.createElement('canvas');

MV3

let canvas = new OffscreenCanvas(width, height);

在完成这些修改之后,需要将你的background scripts 修改为service worker,在浏览器中重新加载你的扩展,看看它是否正常工作。

5) 执行脚本executeScript

如果你的代码使用executeScript的code属性执行任意字符串,有两种方法来更改它。同时,不使用chrome.tabs.execute脚本,需要用 script 替换标签,这样它将是 chrome.script .executeScript

将代码移植到文件

你需要将代码的值移动到一个新文件,并使用executeScript的 file 属性。

之前

chrome.tabs.executeScript({
    code: alert("Hello, World!")
});

修改为

alert(“Hello, World!”) 放到一个新文件(让我们叫它 Hello - World .js):

alert("Hello, World!");
chrome.scripting.executeScript({
    file: 'hello-world.js'
});

将代码放到Function中

如果你的代码可以放在一个函数中,可以将它移动到同一个文件中的一个函数中,然后将execute escripts的 function 属性赋值给你创建的函数:

function greeting() {
    alert("Hello, World!");
}

chrome.scripting.executeScript({
    function: greeting
});

3、其它需求检查的

这里有一个列表,列出了你需要在代码中寻找的要更改的内容:

1、如果你的扩展使用 webRequest API,它通常用于强制安装扩展的企业设置,你需要用declarativentrequest API 替换它。
2、如果你在内容脚本中发出任何CORS请求,请将它们移动到service worker中。

3、不再允许远程托管代码。你需要找到另一种方法来执行远程托管的代码。Chrome的文档建议使用 配置驱动功能和逻辑,这个意思就是说将配置本地化,然后执行用远程的web服务来执行。
4、请查看 API参考,了解可能正在使用的已弃用的API或方法。

好了,以上就是本篇主要内容,Manifest V3的新特性让扩展更安全,其实长远看是有好处的,这样浏览器扩展也不会被滥用,只是之前的MV2一些用法和写法需要做一些调整,工作量应该不会很大,逐条检查自己产品中存在的问题,相信问题一定能够解决,祝大家产品越做越好!