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)的时间表
- 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新特性概要
declarativentrequest 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": [ "http://tahub.app/*" ], ... }
MV3
{ ..., "host_permissions": [ "http://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_action
和 page_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] }]
此外还支持其它的属性,用于设定不同的规则: matches
、 extension_ids
、 use_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('http://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一些用法和写法需要做一些调整,工作量应该不会很大,逐条检查自己产品中存在的问题,相信问题一定能够解决,祝大家产品越做越好!