【发布时间】:2015-12-16 08:42:36
【问题描述】:
我的团队拥有一个 Chrome 扩展程序,而另一个团队也有一个类似的扩展程序,但很快就会被弃用,因此我们将接管他们所有现有用户。问题来了 - 有没有办法将用户从他们的扩展无缝迁移到我们的扩展? IE。有没有办法从用户端自动升级到我们的扩展?
【问题讨论】:
-
除非你想维护两个独立的版本。
标签: google-chrome google-chrome-extension
我的团队拥有一个 Chrome 扩展程序,而另一个团队也有一个类似的扩展程序,但很快就会被弃用,因此我们将接管他们所有现有用户。问题来了 - 有没有办法将用户从他们的扩展无缝迁移到我们的扩展? IE。有没有办法从用户端自动升级到我们的扩展?
【问题讨论】:
标签: google-chrome google-chrome-extension
没有无缝的方法,因为明显的安全原因,扩展程序无法安装其他扩展程序(即使有"management" 权限),但这里有一个可能的升级路径。
我将调用“旧”扩展 A 并假设其 ID 为 "extension_a_id",而“新”扩展 B 并假设其 ID 为“extension_b_id”。
确保扩展可以相互通信。除非您在清单中明确定义"externally_connectable",否则默认情况下应该是这种情况;如果这样做,请确保扩展 B 包含 "extension_a_id" ID,反之亦然。
更新扩展 B 以包含响应来自 A 的请求的代码在所有后续步骤中。在您有理由确定大多数安装基础都具有此版本(可能等待一周左右)之前,请不要继续。
//// Extension B (background code) ////
chrome.runtime.onMessageExternal.addListener(
function(message, sender, sendResponse) {
if(sender.id && sender.id == "extension_A_id") {
/* ..processing code.. */
}
}
);
在扩展 A 中,添加检查扩展 B 是否已安装。通过 ping 来执行此操作:
//// 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
});
如果在第 3 步中没有安装扩展 B,请提醒用户安装它:显示一个页面,解释为什么需要升级并链接到 CWS 列表。此步骤需要用户输入。
如果扩展 B 已在步骤 3 中安装,则将用户选项转移过来并自行卸载:
//// 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});
}
安装扩展程序 B 后,向(可能已安装的)扩展程序 A 发送消息,告知可以立即开始传输:
//// 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);
}
}
}
);
使用上述所有内容发布对扩展 B 的更新。
结果:
ignoreResponse 会吞噬消息错误;最后一个问题是不要用 A 的偏好来破坏 B 的偏好;留给读者作为练习(也取决于实现)。
【讨论】: