manifest_version是什么?
manifest_version代表此扩展程序使用的 manifest.json 版本,目前主流版本为2,最新版本为3
为什么要升级MV3?
自2023年起,Chrome应用商店将不再接受Manifest V2扩展,构建新扩展需要升级到Manifest V3。以下为Manifest V2支持时间线:
Manifest V2 to V3有哪些变化
参考:
Chrome Extension Tutorial: Migrating to Manifest V3 from V2
How to migrate manifest version 2 to v3 for chrome extension?
manifest.json配置
- page_action和browser_action在MV3中统一到action下
// Manifest v2
"browser_action": {...}
"page_action": {
"default_icon": "images/icon.png",
"default_title": "Banner开发调试插件",
"default_popup": "index.html"
},
// Manifest v3
"action": {...}
- 在MV3中,background persistent被弃用,background scripts被替换为background service_worker
// Manifest v2
"background": {
"scripts": ["static/js/background.js"],
"persistent": true
},
// Manifest v3
"background": {
"service_worker": "static/js/background.js"
},
- web_accessible_resources类型由字符串数组变更为对象
// Manifest v2
"web_accessible_resources": ["/static/js/*.js"]
// Manifest v3
"web_accessible_resources": [
{
"resources": [
"/static/js/*.js"
],
"matches": [
"<all_urls>"
],
"extension_ids": []
}
],
- content_security_policy类型由字符串变更为对象,并且script-src和worker-src指令可能只有这些值 :‘self’, ‘none’, ‘wasm-unsafe-eval’
// Manifest v2
"content_security_policy": "default-src 'self'"
// Manifest v3
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
}
消息通信
在MV2中,chrome.extension.onMessage.addListener()是很常用的content向background通信的手段,但在MV3中,需要改写为chrome.runtime.onMessage.addListener()
常见问题
问题一
【报错】‘chrome’ is not defined
【解决】添加注释
【参考】Using chrome api with React.js
问题二
【报错】Refused to execute inline script because it violates the following Content Security Policy directive: “script-src ‘self’ ‘wasm-unsafe-eval’”. Either the ‘unsafe-inline’ keyword, a hash (‘sha256-Rltx/b//LIKPauTaz2gv4cpsZ0YVU5h3PTnfuiTtV/U=’), or a nonce (‘nonce-…’) is required to enable inline execution.
【解决】MV3不允许注入动态脚本,如果要运行动态脚本,可以让受信任的静态脚本获取远程脚本实现,注意引入的js文件需要加入web_accessible_resources获取权限,详见问题三
function nullThrows(v) {
if (!v) {
throw new Error("It's null")
}
return v
}
function active() {
const mockDataNode = document.getElementById('banner-active');
if (mockDataNode) {
return null;
}
const myScript = document.createElement('script');
myScript.src = chrome.runtime.getURL('static/js/active.js');
myScript.id = 'banner-active';
myScript.onload = function () {
console.log("active script injected");
this.remove();
};
nullThrows(document.body || document.documentElement).appendChild(myScript);
}
【参考】Chrome extension manifest v3 Content Security Policy
问题三
【报错】Denying load of chrome-extension://ddoklifpkebknaekabdfkgmleofcbihn/static/js/inject.js. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
【解决】引入的js没有执行权限,将需要插入目标页面的js加入web_accessible_resources中
"web_accessible_resources": [
{
"resources": [
"/static/js/*.js"
],
"matches": [
"<all_urls>"
],
"extension_ids": []
}
],
【参考】web_accessible_resources - Mozilla | MDN
Injecting a script tag from a content script to an iframe with data URI src throws a ‘web_accessible_resources’ error even tho it’s set correctly