如何检查页面 JavaScript 是否安装了 Firefox WebExtension?
How to check if a Firefox WebExtension is installed or not with page JavaScript?
我已经为 Firefox 开发了一个 WebExtension,我的网站使用该扩展作为先决条件。我需要以编程方式检查扩展是否已安装,如果未安装则要求用户安装它。
我无法找到一种方法来检查我的扩展程序是否已安装在用户的浏览器中。
编者注:Firefox 中可用的方法与 available in Chrome 中的方法不同,因此此问题不重复。
开头的重要说明:如果没有扩展程序的明确帮助,页面无法查询是否安装了扩展程序。这样做是为了防止浏览器指纹识别and/or 如果安装了某些扩展,防止网站拒绝内容。
WebExtensions 在很大程度上建立在与 Chrome 扩展相同的原则之上。因此,这个问题是相关的:Check whether user has a Chrome extension installed.
但是,Chrome 中可用的一些最佳方法目前在 Firefox 中不可用:
您不能使用 external messaging from a webpage(通过 externally_connectable
),因为它在 FF 中不可用。
你不能use web-accessible resources for checking presence since Firefox intentionally shields them from fingerprinting:
The files will then be available using a URL like:
moz-extension://<random-UUID>/<path/to/resource>
This UUID is randomly generated for every browser instance and is not your extension's ID. This prevents websites from fingerprinting the extensions a user has installed.
因此,您有哪些选择?页面不能直接与扩展上下文(后台)对话,后台也不能直接影响页面;您需要 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 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
}
});
你可以用类似的方法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
}
我已经为 Firefox 开发了一个 WebExtension,我的网站使用该扩展作为先决条件。我需要以编程方式检查扩展是否已安装,如果未安装则要求用户安装它。
我无法找到一种方法来检查我的扩展程序是否已安装在用户的浏览器中。
编者注:Firefox 中可用的方法与 available in Chrome 中的方法不同,因此此问题不重复。
开头的重要说明:如果没有扩展程序的明确帮助,页面无法查询是否安装了扩展程序。这样做是为了防止浏览器指纹识别and/or 如果安装了某些扩展,防止网站拒绝内容。
WebExtensions 在很大程度上建立在与 Chrome 扩展相同的原则之上。因此,这个问题是相关的:Check whether user has a Chrome extension installed.
但是,Chrome 中可用的一些最佳方法目前在 Firefox 中不可用:
您不能使用 external messaging from a webpage(通过
externally_connectable
),因为它在 FF 中不可用。你不能use web-accessible resources for checking presence since Firefox intentionally shields them from fingerprinting:
The files will then be available using a URL like:
moz-extension://<random-UUID>/<path/to/resource>
This UUID is randomly generated for every browser instance and is not your extension's ID. This prevents websites from fingerprinting the extensions a user has installed.
因此,您有哪些选择?页面不能直接与扩展上下文(后台)对话,后台也不能直接影响页面;您需要 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 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 } });
你可以用类似的方法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 }