开发环境操作系统: Windows 7企业级LTS
浏览器兼容性最低要求:从2018年起,应该支持所有边缘浏览器、火狐浏览器、Chrome浏览器。
当前正在进行的问题:无法在dev工作站上运行VM;无法运行Windows10VM来调试Microsoft扩展。
解释:
如何以不同的方式处理内容脚本:
browser.runtime.sendMessage使用回调,并返回undefined。browser.runtime.sendMessage使用承诺,并返回承诺。chrome.runtime.sendMessage使用回调,并返回undefined。根据各种参考资料:
https://www.smashingmagazine.com/2017/04/browser-extension-edge-chrome-firefox-opera-brave-vivaldi/
在内容脚本上,可以在顶部声明以下JavaScript片段,以便创建一个可以在其他地方引用的全局变量:
//Global "browser" namespace definition.
window.browser = (function() {
return window.msBrowser || window.browser || window.chrome;
})();不幸的是,由于我遇到的问题(VM没有运行),我无法判断是否仍在使用window.msBrowser。当我在使用时处理消息回调时,这个解决方案对我没有帮助。
尽管如此,我的主要问题是:如何编写能够正确处理回调的消息传递函数?
目前,我正在使用以下代码:
function sendGlobalMessage(messageRequest, callback) {
if (chrome && window.openDatabase) {
//This is Chrome browser
chrome.runtime.sendMessage(messageRequest, callback);
}
else if (browser) {
try {
//Edge will error out because of a quirk in Edge IndexedDB implementation.
//See https://gist.github.com/nolanlawson/a841ee23436410f37168
let db = window.indexedDB.open("edge", (Math.pow(2, 30) + 1));
db.onerror = function(e) {
throw new Error("edge is found");
};
db.onsuccess = function(e) {
//This is Firefox browser.
browser.runtime.sendMessage(messageRequest).then(callback);
};
}
catch (e) {
//This is Edge browser
browser.runtime.sendMessage(messageRequest, callback);
}
}
}我真的觉得这是一个麻烦的解决方案,因为代码是基于浏览器平台的排他性怪癖,以便分离chrome.runtime.sendMessage和browser.runtime.sendMessage API调用,以便在各自的平台中处理回调。我真的想要改变这一点。
因此,我想问的是,有什么更好的方法来检测不同的平台,而同时正确地处理消息传递回调()?
提前谢谢。
发布于 2018-05-30 14:29:01
我相信我解决了它。
编辑:最终版本(更新更稳定,消息传递更少):
//Global "browser" namespace definition, defined as "namespace". Can be renamed to anything else.
window.namespace = (function() {
return window.browser || window.chrome;
})();
function sendGlobalResponse(message, callback){
if (window.namespace === window.chrome) {
//Chrome
window.namespace.runtime.sendMessage(message, callback);
}
else if (window.namespace === window.browser) {
//Using instanceof to check for object type, and use the returned evaluation as a truthy value.
let supportPromises = false;
try {
supportPromises = window.namespace.runtime.getPlatformInfo() instanceof Promise;
}
catch(e) { }
if (supportPromises){
//Firefox
window.namespace.runtime.sendMessage(message).then(callback);
}
else {
//Edge
window.namespace.runtime.sendMessage(message, callback);
}
}
}(原文):
最终版本(现已过时):
//Global "browser" namespace definition.
window.namespace = (function() {
return window.browser || window.chrome;
})();
function sendGlobalResponse(message, callback){
if (window.namespace === window.chrome) {
//Chrome
window.namespace.runtime.sendMessage(message, callback);
}
else if (window.namespace === window.browser) {
let returnValue = window.namespace.runtime.sendMessage({});
if (typeof returnValue === "undefined"){
//Edge
window.namespace.runtime.sendMessage(message, callback);
}
else {
//Firefox
window.namespace.runtime.sendMessage(message).then(callback);
}
}
}在第二个if语句中,通过检查window.browser.runtime.sendMessage的返回值是Promise还是undefined,我们可以检测平台是Firefox还是Edge。
我认为这是处理内容脚本上的消息传递回调/消息响应的唯一解决方案。
我真的想不出比这更好的解决办法了。所以从现在开始我就用这个。
但是,如果其他人知道更好的方法,在每个函数调用中不需要为Firefox和Edge发送1条额外的虚拟消息,那就太好了!
糟糕的是,内容脚本中的任何内容都不是持久的,即使您存储了运行代码的平台的信息,在筛选出要调用哪个runtime.sendMessage函数之前,仍然必须从后台脚本中获取信息,所以这并不能真正节省很多时间。
https://stackoverflow.com/questions/50605931
复制相似问题