问题描述
我的团队拥有Chrome扩展程序,另一个团队有类似的扩展程序,但不久将会被弃用,因此我们将接管所有现有用户。问题来了 - 是否有将用户从其扩展迁移到我们无缝的方式?即有没有一种方法可以从用户端自动升级到我们的扩展名? 有
没有无缝的方式,至于显而易见的安全原因,扩展无法安装其他扩展(即使使用management
权限),但这里有一个可能的升级路径。
我会调用旧扩展名A并假定它的标识符是extension_a_id
,以及new扩展名B和假设它的ID是`extension_b_id'。
-
确保扩展名可以相互交谈除非你专门定义,应该是默认情况;如果你这样做,确保扩展B包括
extension_a_id
ID,反之亦然。 -
更新扩展B以包含响应来自A 的请求的代码在所有后续步骤中。
////扩展B(后台代码)////
chrome.runtime.onMessageExternal.addListener(
函数(message,sender,sendResponse){
if(sender.id& amp; sender.id ==extension_A_id){
/ * ..处理代码.. * /
}
}
);
-
在扩展A中,添加一个检查扩展B的安装。通过ping它可以实现:
////扩展名A ////
chrome.runtime.onStartup.addListener(function(){
isNewInstalled(function(response){
if(response){
transferPreferences(response.versionB); //参见步骤5
} else {
// Nag用户安装,请参阅第4步
}
});
});
函数isNewInstalled(callback){
chrome.runtime.sendMessage(
extension_B_id,
{areYouThere:true},
passResponseOrFalse(callback)
);
}
函数passResponseOrFalse(回调){
返回函数(响应){
//评估chrome.runtime.lastError
//很重要以防止不可捕捉的异常,请参阅http://stackoverflow.com/q/28431505
if(chrome.runtime.lastError ||!response){
callback(false);
} else {
callback(response);
}
}
}
////扩展B(处理代码)////
//发送版本号以防万一b $ b if(message.areYouThere)sendResponse({
versionB:chrome.runtime.getManifest()。version
});
-
如果在步骤3中没有安装扩展B,请用户安装它:show该页面解释了为什么需要升级并链接到CWS列表。如果在步骤3中已经安装了扩展名B,请转移用户选项并自行卸载:
$ b -
安装扩展B时, A:转账可以立即开始:
////扩展B,后台代码// //
chrome.runtime.onInstalled.addListener(function(details){
/ * .. may may check details.reason and new version .. * /
chrome.runtime.sendMessage(
extension_A_id,
{iAmHere:true,versionB:chrome.runtime.getManifest()。version},
ignoreResponse
);
});
function ignoreResponse(response){
//再次评估以避免异常;
//如果需要的话,这是检查A是否仍然安装的地方
return chrome.runtime.lastError;
}
////扩展A,后台代码////
chrome.runtime.onMessageExternal.addListener(
函数(message,sender,sendResponse) {
if(sender.id&& sender.id ==extension_B_id){
if(message.iAmHere){
sendResponse({
versionA:chrome。 runtime.getManifest()。version
});
transferPreferences(message.versionB);
}
}
}
);
-
使用上述所有功能发布扩展B的更新。
$ b
////扩展名A ////
函数transferPreferences(versionB){
/ * ..验证B的版本.. * /
var prefs = {};
/ * ..填充需要传输数据的prefs(JSON编码).. * /
chrome.runtime.sendMessage(
extension_B_id,
{
versionA:chrome.runtime.getManifest()。version,
preferences:prefs
},
passResponseOrFalse(goodbyeCruelWorld)
);
}
函数goodbyeCruelWorld(响应){
if(response.processed){
//不需要管理权限
chrome.management.uninstallSelf ();
} else {
console.warn(现在不是我该死的时候了。);
}
}
////扩展B,处理代码////
if(message.preferences){
/ * ..验证message.versionA和处理message.preferences .. * /
sendResponse({processed:true});
}
结果:
ignoreResponse
会吞噬消息错误;
最后一个问题是不要把B的偏好与A的偏好打成一片;作为练习留给读者(也取决于实施情况)。
My team owns a Chrome extension, and the other team has a similar extension but sooner will be deprecated, so we will take over all their existing users. Here comes the question - is there a way to migrate users from their extension to ours seamless? I.e. is there a way to auto-upgrade to our extension from user end?
There is no seamless way, as for obvious security reasons extensions can't install other extensions (even with "management"
permission), but here's a possible upgrade path.
I'll call the "old" extension A and assume its ID is "extension_a_id"
, and the "new" extension B and assume its ID is `extension_b_id".
Make sure that extensions can talk to each other. Unless you specifically define
"externally_connectable"
in the manifest, that should be the case by default; if you do, make sure that extension B's includes the"extension_a_id"
ID and vice versa.Update extension B to include code responding to requests from A in all following steps. Do not proceed until you're reasonably sure most of the install base has this version (maybe wait a week or so).
//// Extension B (background code) //// chrome.runtime.onMessageExternal.addListener( function(message, sender, sendResponse) { if(sender.id && sender.id == "extension_A_id") { /* ..processing code.. */ } } );
In extension A, add a check that extension B is installed. Do so by pinging it:
//// Extension A //// chrome.runtime.onStartup.addListener(function() { isNewInstalled(function(response) { if(response) { transferPreferences(response.versionB); // See step 5 } else { // Nag user to install, see step 4 } }); }); function isNewInstalled(callback) { chrome.runtime.sendMessage( "extension_B_id", {areYouThere: true}, passResponseOrFalse(callback) ); } function passResponseOrFalse(callback) { return function(response) { // It's important to evaluate chrome.runtime.lastError // to prevent uncatchable exception, see http://stackoverflow.com/q/28431505 if(chrome.runtime.lastError || !response) { callback(false); } else { callback(response); } } } //// Extension B (processing code) //// // Send version number just in case if(message.areYouThere) sendResponse({ versionB: chrome.runtime.getManifest().version });
If extension B is not installed in step 3, nag the user to install it: show a page that explains why it is needed to upgrade and link to the CWS listing. This step requires user input.
If the extension B is already installed in step 3, transfer user options over and self-uninstall:
//// Extension A //// function transferPreferences(versionB) { /* ..validate version of B.. */ var prefs = {}; /* ..fill prefs with data that needs to be transfered (JSON-encodable).. */ chrome.runtime.sendMessage( "extension_B_id", { versionA: chrome.runtime.getManifest().version, preferences: prefs }, passResponseOrFalse(goodbyeCruelWorld) ); } function goodbyeCruelWorld(response) { if(response.processed) { // Does not require management permission chrome.management.uninstallSelf(); } else { console.warn("It is not my time to die yet."); } } //// Extension B, processing code //// if(message.preferences) { /* ..validate message.versionA and process message.preferences.. */ sendResponse({processed: true}); }
When extension B is installed, message the (possibly installed) extension A that the transfer can start immediately:
//// Extension B, background code //// chrome.runtime.onInstalled.addListener(function(details) { /* ..maybe check details.reason and new version.. */ chrome.runtime.sendMessage( "extension_A_id", {iAmHere: true, versionB: chrome.runtime.getManifest().version}, ignoreResponse ); }); function ignoreResponse(response) { // Again, evaluate to avoid exceptions; // if needed, this is the place to check if A is still installed return chrome.runtime.lastError; } //// Extension A, background code //// chrome.runtime.onMessageExternal.addListener( function(message, sender, sendResponse) { if(sender.id && sender.id == "extension_B_id") { if(message.iAmHere) { sendResponse({ versionA: chrome.runtime.getManifest().version }); transferPreferences(message.versionB); } } } );
Publish an update to extension B with all of the above.
Result:
- Users that have B installed won't notice anything, since
ignoreResponse
will gobble up the messaging error; - Users that have both installed will initiate transfer as soon as B updates and it will quietly finish;
- Users that only have A will be nagged on every extension restart to install B instead, upon which the transfer will start automatically.
One last concern is not to clobber the preferences of B with ones from A; left as an exercise to the reader (and also depends on the implementation).
这篇关于如何更换/升级Chrome扩展与另一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!