我手上负责的谷歌插件v3版本对v2的替代进程已经基本完成了。对于大部分非屏蔽广告功能的插件来说,其实主要难点就在于跨域拨号方式的修改。v3拨号废弃了ajax,采用了fetch。关于fetch的使用我建议去查询fetch的使用方法。本文要说的重点在于对头文件的修改。
v3要实现头文件修改需要依靠重定向规则,而重定向规则可以用两种形式实现。
一种是静态规则,该种方法的弊端在于定性之后,对当个接口修改规则或添加接口时。都需要替换底层文件,对于上传到应用市场的插件这不是太大问题。但对于需要客户手动离线安装的插件来说,会麻烦很多,增加不必要的用户操作。
另一种是采用动态规则修改,相对第一种来说就灵活了很多。用点比较狗的方法,基本可以达到v2版所能实现的那种头文件修改直接跟接口放到一起的效果。我自己选择的也是第二种。
静态规则
manifest.json
{
"name": "My extension",
...
"declarative_net_request" : {
"rule_resources" : [
{
"id": "rule",
"enabled": true,
"path": "rule.json"
}]
},
"permissions": [
"declarativeNetRequest",
"declarativeNetRequestFeedback",
...
],
...
}
然后在目录下新建文件rule.json。 rule.json
[{
"id": 1,
"priority": 1,
"condition": {
"regexFilter": "https://XXX.XXX.XXX/api/*",
"resourceTypes": ["xmlhttprequest"]
},
"action": {
"type": "modifyHeaders",
"requestHeaders": [
{
"header": "h1",
"operation": "set",
"value": "v4"
},
{
"header": "foo",
"operation": "remove"
}]
}
}]
动态规则
动态规则无需在manifest.json中做declarative_net_request的配置。而是需要在服务工作中使用chrome.declarativeNetRequest.updateDynamicRules。 service_worker.js(即v3中代替background.js的那个东西)
let rule={
removeRuleIds: [1],//删除原有的规则一
addRules: [{
"id": 1,
"priority": 1,
"condition": {
"urlFilter": "https://XXX.XXX.XXX/api/*",
"resourceTypes": ["xmlhttprequest"],
},
"action": {
"type": "modifyHeaders",
"requestHeaders": [
{
"header": "h1",
"operation": "set",
"value": "v4"
},
{
"header": "foo",
"operation": "remove"
}]
}
}]
};
//注意这一句,不是画蛇添足,往下看说明
rule.addRules.forEach((item)=>{
item.condition.domains=[chrome.runtime.id]
})
//写入规则
chrome.declarativeNetRequest.updateDynamicRules(rule,function(){
//这是为了查看规则是否写入成功,正式使用时可以删除
chrome.declarativeNetRequest.getDynamicRules(rules=>console.log(rules))
})
这一段其实是被我强行拿出来凑一起举例了,实际使用中rule参数应该是进行跨域拨号前将其传到service_worker中,然后再在service_worker中写入插件id限制修改头文件的范围最后updateDynamicRules;
这个方法好处在于无限接近于v2版的修改规则头,最大程度避免了同一插件使用相近url时产生的影响。坏处在于使用多个跨域拨号时需要采用异步操作,否则会有修改头文件失误的可能性。
避免这些问题,还可以有个折中的方法。将插件一个页面所需的跨域规则全部统计出来,在加载时就将其写入规则。在所需跨域接口不多,且不会稳定不需要经常改动的情况下,这不失为最佳的方案。
请重点注意
1、rule中你要影响到的网址需要在manifest.json的host_permissions中有。其实想想也是你主机权限都不给你让插件怎么去改这个api的拨号头呢。
2、为了避免对正常网页影响,规则集中一定要使用domains!!!!
3、关于rule参数我介绍我记得有专门的文档,写文的时候我没搜到。基本常用的就是举例上的这些参数;requestHeaders拨号头,responseHeaders响应头;参数的修改set,删除remove。具体感兴趣的可以自己去找文档详细了解。