前言:Chrome从22年6月开始,新发布插件只接受V3版,V2版只支持已发布的更新,23年1月后V2版将不再支持更新,23年6月将会全部从Chrome应用商店下架

本文章主要是把ChromeV3的插件配置项进行一个大概的注解,且基本上开发一个V3的插件可以使用这个配置进行开发,只需要改动部分配置参数的值

manifest.json配置文件

{
  //chrome插件的版本
  "manifest_version": 3,
  
  //插件名称
  "name": "ChromeName",
  
  //插件版本号
  "version": "1.0.0",
  
  //插件描述,Plugin_Desc是多语言的key,chrome插件支持多语言配置,__MSG_xxx__
  "description": "__MSG_Plugin_Desc__",
  
  //默认语言(如果当前浏览器设置的语言不存在多语言配置文件,则默认中文),Chrome插件的多语言只能根据当前浏览器设置的语言来设定,无法通过代码更改语言
  "default_locale": "zh_CN",
  
   //内容安全政策,V2的value是字符串,V3是对象
  "content_security_policy": {
    //原文:此政策涵盖您的扩展程序中的页面,包括 html 文件和服务人员;具体不是很明白,但是参数值得是self,即当前自己
    "extension_pages": "script-src 'self'; object-src 'self'",
	
	//原文:此政策涵盖您的扩展程序使用的任何[沙盒扩展程序页面];具体不是很明白,但是参数值得是self,即当前自己
    "sandbox": "sandbox allow-scripts; script-src 'self'; object-src 'self'"
  },
  
   //key,发布插件后会给一个key,把那个key的值放这里
  "key": "xxx",
  
  //icon,浏览器扩展程序管理里面的图标、浏览器右侧插件图标点开的下拉菜单展示的已开启插件的图标、以及插件详情页的标签卡的那个小图标
  "icons": {
    "16": "static/img/logo-16.png",
    "19": "static/img/logo-19.png",
    "38": "static/img/logo-38.png",
    "48": "static/img/logo-48.png",
    "128": "static/img/logo-128.png"
  },
  
  //背景页,后台脚本引入,v2是scripts:[xxx,xxx],可以引入多个js文件,v3是service_worker:'xxx',只能引入一个js,v3版最大的改动应该就是这里了,扩展程序管理界面的插件的那个“背景页”也将变成“Service Worker”,改动之后background.js将和浏览器完全分离,即无法调用window和ducoment对象
  //可以看介绍:
  //1、//developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#background-service-workers;
  //2、//developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/
  
  "background": {
    "service_worker": "background.js",
    "type": "module" //设置type为module之后,background.js里面才能使用import导入其它脚本文件
  },
  
  //注入脚本,值是个数组对象,可以有多个对象
  "content_scripts": [
    //每个对象代表一个注入的配置
    {
	    //需要在指定页面注入的js脚本文件
      "js": [
        "xxx.js",
        "xxx.js",
      ],
	   //需要注入js脚本文件的指定页面
      "matches": [
        "https://*.csdn.net/*",
        "https://*.xxx.com/*"
      ],
       //不允许注入js脚本文件的指定页面
 	   "exclude_matches": ["https://*.xxx.com/*"],
	   //什么时候注入的js脚本,document_start=页面加载开始时,document_end=页面加载结束时
      "run_at": "document_end"
    }
  ],
  
  //API权限,需要使用某些API时需要设置该API权限才行
  "permissions": [
	  "contextMenus", //自定义创建右键菜单API
	  "tabs", //tab选项卡API
	  "storage", //缓存API
	  "webRequest", //监听浏览器请求API
	  ...
  ],
  
  //主机权限,在背景页backgroud.js里面或者popup页面走请求时,请求域名的白名单权限,如果没添加的则请求会失败
  "host_permissions": [
    "https://*.csdn.net/*",
    "https://*.xxx.com/*"
  ],
  
  //动作API,原文:在 Manifest V2 中,有两种不同的 API 来实现操作: `"browser_action"` 和 `"page_action"` . 这些 API 在引入时扮演了不同的角色,但随着时间的推移它们变得多余,因此在 Manifest V3 中,我们将它们统一为单个 `"action"` API; 
  //v3配置,在v3中需要把browser_action废弃了,需要改成action,同时插件图标的点击监听事件也是一样,把chrome.browserAction改成chrome.action
  //如果不添加action这个配置参数的话,chrome.action.onClicked.addListener()这个监听方法会无效
 "action": {
    "default_icon": {
        "19": "static/img/logo-19.png"
    },
    "default_title": "插件标题"
 }
  
  //通过网络访问的资源,v2是提供一个数组,v3得提供数组对象,每个对象可以映射到一组资源到一组 URL 或扩展 ID
  "web_accessible_resources": [{
  	//允许访问的资源路径,数组传多个参数
    "resources": ["*/img/xxx.png", "*/img/xxx2.png"],
	
	//允许访问资源的页面
    "matches": [
      "https://*.csdn.net/*",
      "https://*.xxx.com/*"
    ]
  }],
  
  //指定哪些其他页面和插件可以通过 runtime.connect 和 runtime.sendMessage 连接到插件
  //如果未在清单中声明 externally_connectable 键,则所有插件都可以连接,但任何网页都无法连接
  //如果在清单中声明了externally_connectable,但是未指定 ids: ["*"],则其他插件将无法连接到插件
  "externally_connectable": {
      "ids": ["xxx"], //指定哪些第三方插件可以给我们插件发送消息
      "matches": [ //指定哪些第三方页面可以给我们插件发送消息
        "https://*.csdn.net/*",
        "https://*.xxx.com/*"
      ]
  }
}

消息监听

1、插件内部发送消息

//onMessage消息监听
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    console.log(request.text); //打印出来的值:“我是个测试内容”
    sendResponse('触发成功了'); //返回一个内容到发送消息的回调函数中
});
//发送消息,触发上面的onMessage
chrome.runtime.sendMessage('', {text: '我是个测试内容'}, function (msg) {
    console.log(msg); //打印的内容是:“触发成功了”
});

2、外部网站给插件发送消息,需要在manifest里面配置externally_connectable:{matches:[“https://*.xxx.com/”]}
只有配置了对应的地址的页面才能给插件发送消息

//onMessageExternal消息监听
chrome.runtime.onMessageExternal.addListener(function (request, sender, sendResponse) {
    console.log(request.text); //打印出来的值:“我是个测试内容”
    sendResponse('外部触发成功'); //返回一个内容到发送消息的回调函数中
});
//发送消息,触发上面的onMessageExternal
//第一个参数是插件Id,指定要发送给哪个插件
//第二个参数是想要传给插件的数据信息
//第三个是让插件那边调用的回调函数,触发回来
chrome.runtime.sendMessage('chromeId', {text: '我是个测试内容'}, function (msg) {
    console.log(msg); //打印的内容是:"外部触发成功"
});

注意:内部发送sendMessage不会触发到onMessageExternal,
外部发送sendMessage不会触发到onMessage

3、注意onMessage消息监听事件触发sendResponse回调函数的时机,如果需要调用sendResponse函数给消息发送者响应,则需要注意同步和异步线程的差异

示例:
//onMessage消息监听
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    console.log(request.text); //打印出来的值:“我是个测试内容”
    
    //1、如果在同步线程中回调sendResponse,则return false || undefined,或者不return都可以,消息发送者那边都可以接收到这边传过去的参数
    sendResponse('同步线程中回调触发'); //返回一个内容到发送消息的回调函数中
    return false || undefined;
    
    //2、如果是在异步线程中回调sendResponse,则必须是return true,否则消息发送者那边在return的时候就被触发到回调了,然后参数得到的是undefined
         然后异步里面的sendResponse回调属于无效回调
         
    //2-1、异步线程return flase || undefined
    setTimeout(() => {
        sendResponse('异步线程中回调触发'); //这里触发属于无效回调
    }, 1000);
    return false || undefined; //这里return的时候,消息发送者那边就已经被触发回调了,上面延时器里面的回调将无效
    
    //2-2、异步线程return true
    setTimeout(() => {
        sendResponse('异步线程中回调触发'); //这里触发属于有效回调
    }, 1000);
    return true; //这里return的时候,消息发送者那边还不会被触发回调了,上面延时器里面的回调调用才触发
});

//发送消息,触发onMessage
//第一个参数是插件Id,指定要发送给哪个插件,因为是内部发送,所以可以不用指定,直接传空字符串就好了
//第二个参数是想要传给插件的数据信息
//第三个是让插件那边调用的回调函数
chrome.runtime.sendMessage('', {text: '我是个测试内容'}, function (msg) {
     //1、同步线程下获得到的msg=‘同步线程中回调触发’
     //2-1、异步线程下,且onMessage监听消息函数最后面不是return true,则获得到的msg=undefined
     //2-2、异步线程下,且onMessage监听消息函数最后面是return true,则等待一秒后获得到msg=‘异步线程中回调触发’
    console.log(msg);
});
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐