1 主流方案及尝试
现在浏览器插件中,大多采用直接调用远程代码的方式进行热更新,由于安全策略逐步增强,越来越不支持热更新了;chrome在新v3版本插件中直接给禁止了;对于v2版本则即将废弃使用。
或者要翻墙到google应用商店提交审核,才能热更新。
2 当前问题
1、由于安全策略逐步增强,越来越不支持热更新了,之前可以直接调用远程资源的方法均被禁止了;
2、chrome插件开发中,v2版本是支持热更新的,但明年v2版本将被废弃到;
3、所有chrome插件都要尽快升级成v3版本,然而v3版本不支持热更新。
4、需要要到翻墙到google应用商店提交审核,等审核通过后,且用户本身要至此翻墙才能进行插件热更新。
3 技术原理
chrome.runtime.getURL获取js地址的方法是新版v3浏览器本身支持的方法,可以用它来获取插件安装包中的内部静态资源,来进行加载。
本发明流程如下图所示:
浏览器插件的新版均只允许加载本地资源,而限制外部资源的加载;本发明同样遵循浏览器内核要求,在serviceworker中加载插件中预制资源inject_base.js到页面里,需要直接或间接用chrome.runtime.getURL方法加载inject_base.js资源,然后再从inject_base.js中加载远端inject.js资源即可,此处两步过程可以扩展到三步或更多步骤,但不可省略这两个步骤。
inject.js中会有插件的核心功能资源,当需要热更新插件功能时,直接更新外部资源inject.js即可。
4 方案实施
在遵循浏览器内核安全控制要求下,我们可以如下操作:
1) 先在serviceworker中通过chrome.runtime.getURL获取url地址的方法动态加载预制资源inject_base.js;此处若用chrome.scripting.executeScript方法动态加载预制资源,则需先加载一个桥接资源inject_base_bridge.js,然后再在inject_base_bridge.js中用chrome.runtime.getURL方法动态加载远端indect_base.js,然后进行第二步;
function inject(){
const injectPath = "js/inject.js";
const script = document.createElement("script");
script.setAttribute("type", "text/javascript");
// 重点是这句
script.src = chrome.runtime.getURL(injectPath);
document.body.appendChild(script);
}
该步骤中需要注意的是:不可以直接用chrome.runtime.getURL或chrome.scripting.executeScript这两个方法,而是需要用onMessage监听来动态使用这两个方法,否则后续js资源的加载则只在安装或刷新时生效一次,而不能在每个页面中都成功加载。
function injectJsCode(srcList=["js/inject_base.js"]) {
chrome.tabs.query(
{
active: true,
currentWindow: true,
},
(tabs) => {
if (tabs[0]) {
// 注入插件预制js
let _injectJsList = srcList;
chrome.scripting.executeScript({
target: { tabId: tabs[0].id },
files: _injectJsList,
});
}
}
);
}
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
switch (message.type) {
case "inject-code":
injectJsCode();
return true;
}
});
2)再从inject_base.js中加载远端inject.js资源即可;当发布新功能时,直接发布远端的新版inject.js即可直接热更新插件功能。
具体逻辑如下图所示:
onMessage监听来动态使用擦灰姑娘如方法,确保后续js资源在每个页面中都成功加载;需要从content_scripts中设置发送脚本输入的消息通知:
chrome.runtime.sendMessage(chrome.runtime.id, message, callback)
这样就可以随时愉快的更新插件发布新功能了。
5 方案总结
该方案目前所打的包,在用户直接下载、解压、使用时比较合适;大多在未发布到chrome应用商店时使用较为便捷。若要在chrome官方应用商店发布,则需改造。待后续总结整理…
作者:京东科技 贾玉龙
来源:京东云开发者社区