发布时间:2023-05-24 文章分类:WEB开发, 电脑百科 投稿人:王小丽 字号: 默认 | | 超大 打印

总结一下自己在把Chrome V2版本的插件升级到V3版本的过程中,遇到的一些问题,之前也有发布一章V3版本的manifest.json配置项参数说明,基本也涵盖了下面提到的几个配置项的改动,传送门>>

总结分了两大块,一块是manifest配置文件V2和V3有哪几个配置项不同,一块是升级过程遇到的问题,下面进入正题:

一、manifest.json配置文件中的几个配置项的变动

1、browser_action参数:该参数是设置浏览器右侧插件那里展示的插件图标和标题

//v2配置,v2配置中是用browser_action参数来配置图标和标题,然后右侧插件图标点击时触发的监听事件是chrome.browserAction.onClicked.addListener()
"browser_action": {
  "default_icon": {
    "19": "images/icon19.png"
  },
  "default_title": "插件标题"
}
//v3配置,在v3中需要把browser_action废弃了,需要改成action,同时插件图标的点击监听事件也是一样,把chrome.browserAction改成chrome.action
//如果不添加action这个配置参数的话,chrome.action.onClicked.addListener()这个监听方法会无效
"action": {
  "default_icon": {
    "19": "images/icon19.png"
  },
  "default_title": "插件标题"
}

这里贴一个谷歌翻译的插件截图,插件图标就是前面的Logo,插件标题就是后面的’Google 翻译’,然后当点击红框部分时就会触发上面提到的点击监听事件
记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题

2、background参数:背景页配置参数,v3中背景页改为叫做service worker服务者

//v2配置,在v2配置中的scripts可以填写多个js文件地址,填写进来的这些文件地址都会在背景页中引用进去
"background": {
  "scripts": [
    "js/jquery.js","js/main.js", "js/background.js", ...
  ],
  "persistent": true
}
//v3配置,把scripts数组改成service_worker字符串,只允许引入一个js文件,其他js文件可以在当前引入的js文件里面import引入
"background": {
  "service_worker": "background.js"
},

v2版本后台是叫背景页,上面配置里面添加的js文件都会在背景页里面引入加载进去,v2版本背景页中是可以调用window对象和document对象的(即可以引用jQuery.js之后使用$.ajax去发送请求)

v3版本后台是叫service worker 服务者,上面配置里面只能添加一个js文件,如果还需要引用其它js则只能在那个js文件里面用vue的import引入方式把其它文件引入加载,v3版本的service worker服务者中无法调用window和document对象(即无法引用jQuery.js,也就无法使用$.ajax发送请求了,因为jQuery是基于原生写的,里面有需要用到document对象),且原生的XMLHttpRequest请求也无法使用,以及vue的axios也是,想要调用请求需要用fetch()去进行请求

3、permissions参数:权限配置参数

//v2配置权限,在v2中的权限配置中,ChromeAPI权限和主机权限是一起配置的。
//ChromeAPI权限:需要使用Chrome的一些API的话需要配置对应的API权限,否则会报错未添加权限而无法使用,如tags标签页,contextMenus添加自定义右键菜单项)
//主机权限:主机权限也可以称为请求白名单权限,在背景页backgroud.js里面或者popup页面调用某个网站请求时,增加该网站的白名单权限,如果没添加的则调用请求会报跨域)
"permissions": [
  "tabs",
  "contextMenus",
  "http://*.xxx.com/" //添加xxx域名,则在插件中可以请求xxx网站的接口,如果没加的话请求接口会跨域
]
//v3配置,在v3版本中API权限和主机权限的配置分开了
//ChromeAPI权限
"permissions": ["tabs", "contextMenus", ...],
//主机权限
"host_permissions": ["http://*.xxx.com/", ...]

4、web_accessible_resources参数:允许外部访问Chrome插件中的资源,比如图片资源

//v2配置,数组格式,多个资源逗号添加即可,v2好像不限制外部访问,这里添加了一个图片地址,那么所有网站都可以通过"chrome-extension://chrome扩展程序ID/images/logo.png"绝对地址访问到这张图片
"web_accessible_resources": [
  "images/logo.png"
]
//v3配置,数组对象格式,对象中分了可外部访问的资源以及允许哪些外部网站可以访问该资源,下面这里的配置说明只有在csdn域名下才可以通过"chrome-extension://Chrome扩展程序ID/images/logo.png"绝对地址访问到这张图片,其它域名则无法访问
"web_accessible_resources": [{
  "resources": ["*/images/logo.png"], //resources添加可外部访问的资源
  "matches": [ //matches添加允许访问资源的网站域名
    "https://*.csdn.net/*"
  ]
}]

5、内容安全政策参数:V2的value是字符串,V3是对象

//v2配置,v2版本中可以配置script等通过外部引入,这个content_security_policy配置参数不加或者加上之后相应的值填none
"content_security_policy": "script-src 'none'; object-src 'none'",
//v3配置,v3版本中安全政策配置script引入等信息,都必须填写self,即只允许script标签引用当前插件内部文件,不允许引用外部链接,如果不填写self的话,插件添加到扩展程序时会报错
"content_security_policy": {
   //原文:此政策涵盖您的扩展程序中的页面,包括 html 文件和服务人员;
   "extension_pages": "script-src 'self'; object-src 'self'",
//原文:此政策涵盖您的扩展程序使用的任何[沙盒扩展程序页面](https://developer.chrome.com/docs/extensions/mv3/manifest/sandbox/)。;
   "sandbox": "sandbox allow-scripts; script-src 'self'; object-src 'self'"
},

二、升级V3时遇到的问题

1、添加插件到扩展程序时报错安全策略不允许不安全的策略
造成原因:原因就是上面的安全策略参数没有把script-src设为self
解决方案:把script-src值设置为self即可

2、复制v2版本的permissions配置项到v3时,把配置项改名为host_permissions,添加到扩展程序时报错权限清单配置错误
造成原因:因为V3的API权限配置和主机权限配置是两个参数,host_permissions里面不能添加API权限
解决方案:区分出API权限和主机权限的可配置值,把API权限的信息添加到permissions配置项中,host_permissions主机权限只保留白名单域名信息

3、需要在插件中监听某个页面的请求,使用chrome.webRequest.xxx.addListener方法报错无效
造成原因:因为上面第二条的问题原因,当时直接把webRequestAPI权限删掉了,没有把webRequestAPI权限添加到permissions配置项中
解决方案:添加permissions配置项,并把webRequest添加进去即可使用chrome.webRequest的监听事件

4、使用chrome.webRequest.xxx.addListener方法监听时,第三个参数传blocking报错,在API权限中配置webRequestBlocking了也不行
造成原因:不详!不清楚是不是V3不能用blocking
解决方案:把blocking改成responseHeaders或者requestBody,如果是要监听请求获取请求头参数则改成responseHeaders,如果是要监听请求获取请求体参数则改成requestBody

5、在外部网站直接a标签href="chrome-extension://Chrome扩展程序ID/main.html"跳转到插件popup页,页面报错无法访问
造成原因:V3不能在外部网站通过这种绝对地址跳转的方式访问插件popup页了
解决方案:需要在外部网站通过chrome.runtime.sendMessage给插件发送消息,然后在插件background.js里面监听消息后用chrome.tabs.create({url: url}, function (tabs){})创建一个标签页打开,url是通过chrome.runtime.getURL('main.htm')来拼接的,getURL方法可以获取到当前插件的地址前缀’chrome-extension://chrome扩展程序ID/',然后拼接传进去的参数地址

6、右侧插件图标点击监听事件chrome.browserAction.onClicked.addListener方法失效
造成原因:V3废除了browserAction配置,改为了action,前面的配置文件参数的区别说明中第一点有提到
解决方案:需要在配置文件中添加action配置项,且监听事件改成使用chrome.action.onClicked.addListener方法来监听

7、添加自定义鼠标右键菜单选项chrome.contextMenus.create({})方法报错参数不支持onclick回调函数字段
造成原因:V3中右键菜单的配置项去除了onclick回调函数参数,改为了另一种方式进行监听右键自定义菜单选项点击事件
解决方案:添加右键菜单的点击监听事件函数chrome.contextMenus.onClicked.addListener(function(){})来进行监听

8、V3版本的service worker(原V2的背景页,即background)中不支持window和document对象
造成原因:V3最大的改动就是这一点,原来V2的背景页和浏览器是有关联的,service worker直接和浏览器进行了隔离,导致window对象和document对象都无法使用,比如我们用到了浏览器数据库window.IndexdDB,以及因为没有了document对象,导致在background中无法引用jQuery去使用$.ajax,且原生的XmlHttpRequest请求也无法使用,vue的axios请求也不行
解决方案:V3版本中直接给了indexedDB这么一个参数对象,无需window.indexedDB调用,直接indexedDB调用即可使用浏览器数据库,可以一切照旧,ajax请求则需要换成Fetch请求才行

可以看这两篇介绍background的改动:
1、https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#background-service-workers;
2、https://developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/

9、因为不能用ajax请求,换成fetch请求后,有些请求报错501、500、401等
造成原因:fetch请求头默认参数和ajax请求头默认参数不一致,以及请求参数的格式也会发生变化
解决方案:先找之前的ajax请求,右键可以复制成fetch请求方式查看区别,看下面截图
记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题
记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题

10、fetch请求页面获取到的html返回中文乱码
造成原因:因为fetch请求都是以utf-8来编译的,但是html页面请求需要用gbk编译
解决方案:需要在fetch请求里面返回的数据格式改为arrayBuffer类型,然后接收返回的数据那里用new TextDecoder(‘gbk’).decode()方式转成字符串
记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题
记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题

11、V3的插件详情页,a标签的href不能=“javascript:”,控制台会报不符合安全策略的错误,但是不影响页面操作
造成原因:V3安全策略要求只能是self,页面上不能写js语句,a标签的href="javascript:"被认为执行了js语句,所以会报错
解决方案:把a标签的href="javascript:"去掉即可

12、V3的background.js中,不能使用veal() 和 new Function() 方法来执行字符串代码或者是转义字符串对象了
造成原因:应该也是V3的安全策略原因,不允许执行字符串代码,防止恶意代码攻击,而且本身veal这个方法就是不安全的,网上搜索相关文章都是建议不要使用
解决方案:看之前用veal方法执行的内容是什么,如果是字符串数组或字符串对象,可以用JSON.parse()转义

以上就是在升级过程中遇到的一些问题,至此结束!!!溜了溜了