我无法找到一种方法来检查我的扩展程序是否已经安装在用户的浏览器中。
编辑说明:Firefox中可用的方法与Chrome中可用的方法不同,因此这个问题并非重复。
需要先强调一点:网页不能在没有扩展程序明确帮助的情况下查询是否安装了某个扩展。这是为了防止浏览器指纹识别和/或阻止网站因特定扩展被安装而拒绝内容。
WebExtensions 在很大程度上基于与 Chrome 扩展程序相同的原则。因此,这个问题是相关的:检查用户是否已安装 Chrome 扩展程序。
然而,在 Firefox 中目前有一些最好的方法是不可用的:
你不能使用从网页外部发送消息(通过externally_connectable
),因为它在 FF 中不可用。
文件将通过类似以下 URL 的方式可供使用:
moz-extension://<random-UUID>/<path/to/resource>
这个 UUID 是为每个浏览器实例随机生成的,而不是您扩展程序的 ID。这可以防止网站对用户安装的扩展进行指纹识别。
因此,你有哪些选择?页面无法直接与扩展上下文(后台)通信,而后台也无法直接影响页面;您需要内容脚本来与页面内容交互。
页面代码和内容脚本如何通信?它们彼此隔离,除非内容脚本采取某些措施。
首先,这些适用于 FF 和 Chrome 的通用技巧:
You can create or modify a DOM element on the page from a content script and look for those modifications in the page.
// 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
}
You can use postMessage
to communicate between contexts, though it's clunky to use as a bidirectional channel.
Here's documentation and 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
}
});
You can use custom DOM events in a similar way.
还有一些有趣的火狐浏览器专属方法:
You can share code with the page using exportFunction
or 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
}