我为Firefox开发了一个WebExtension,我的网站使用扩展作为先决条件。我需要以编程方式检查扩展是否已安装,如果没有请求用户安装它。
我无法找到如何检查此扩展程序是否已安装在用户浏览器中的操作的方法。
编者注:Firefox中可用的方法与available in Chrome不同,所以这个问题不重复。
答案 0 :(得分:4)
开始时的重要提示:如果没有来自扩展程序的明确帮助,页面无法查询是否安装了扩展程序。这样做是为了防止浏览器指纹识别和/或阻止网站拒绝内容安装了某些扩展程序。
WebExtensions主要基于与Chrome扩展程序相同的原则。因此,这个问题是相关的:Check whether user has a Chrome extension installed。
但是, Chrome中提供的一些最佳方法目前无法在Firefox中使用:
您无法使用external messaging from a webpage(通过externally_connectable
),因为它在FF中不可用。
自Firefox use web-accessible resources for checking presence以来,您无法intentionally shields them from fingerprinting:
然后可以使用以下网址获取文件:
moz-extension://<random-UUID>/<path/to/resource>
此UUID 为每个浏览器实例随机生成,而不是您的扩展程序ID。这可以防止网站对用户安装的扩展名进行指纹识别。
因此,你有什么选择?页面不能直接与扩展上下文(后台)对话,后台不能直接影响页面;您需要Content script与网页内容进行互动。
页面代码和内容脚本如何通信?除非内容脚本对此有所帮助,否则它们彼此隔离。
首先,在FF和Chrome中都有效的通用技巧:
您可以通过内容脚本在页面上create or modify a DOM element查找页面中的修改。
// Content script
let beacon = document.createElement("div");
beacon.classname = browser.runtime.id;
document.body.appendChild(beacon);
// Page script
// Make sure this runs after the extension code
if (document.getElementsByClassName("expected-extension-id").length) {
// Installed
} else {
// Not installed
}
您可以在上下文之间使用postMessage
进行通信,但使用它作为双向频道非常笨拙。
此处为documentation和sample WebExtension。
// Content script code
window.postMessage({
direction: "from-content-script",
message: "Message from extension"
}, "*");
// Page code
window.addEventListener("message", function(event) {
if (event.source == window &&
event.data.direction &&
event.data.direction == "from-content-script") {
// Assume extension is now installed
}
});
您可以以类似的方式 use custom DOM events 。
还有一些有趣的Firefox特定方法:
您可以share code with the page使用exportFunction
或cloneInto
:
// Content script
function usefulFunction() {
/* ... */
}
const extensionInterface = {
usefulFunction
}
window.wrappedJSObject.extensionInterface =
cloneInto(extensionInterface, window, {cloneFunctions: true});
// Page code
if (typeof window.extensionInterface !== "undefined") {
// Installed
window.extensionInterface.usefulFunction();
} else {
// Not installed
}