如何使用页面JavaScript检查Firefox WebExtension是否已安装?

6
我开发了一个Firefox的WebExtension,我的网站需要先安装这个扩展程序才能使用。我需要通过编程方式检查扩展程序是否已经安装,如果没有安装就要求用户安装。
我无法找到一种方法来检查我的扩展程序是否已经安装在用户的浏览器中。
编辑说明:Firefox中可用的方法与Chrome中可用的方法不同,因此这个问题并非重复。

@TKoL 那样做不会有效。 - Xan
1
关闭为一个经典的Chrome问题的重复;在这方面,WebExtensions与Chrome模型没有显著的区别。 - Xan
1
你是否知道,除了一些小差异外,Firefox扩展的行为方式都是相同的?所有答案(至少是高票答案)都适用。我认为在Firefox中没有可用的机制。 - Xan
Firefox附加组件SDK,我不小心添加了。我知道Chrome和FF都遵循Web扩展API。我不是在谈论开发FF扩展。问题是找到检测扩展的方法。非常清楚。 - Maninder
确实。非常清楚。您需要对扩展进行更改,以使其与网页协作。正如我所说,链接问题中的所有内容都适用,我不知道任何针对FF特定的根本不同的方法。仍然是重复的。 - Xan
显示剩余7条评论
1个回答

9

需要先强调一点:网页不能在没有扩展程序明确帮助的情况下查询是否安装了某个扩展。这是为了防止浏览器指纹识别和/或阻止网站因特定扩展被安装而拒绝内容。

WebExtensions 在很大程度上基于与 Chrome 扩展程序相同的原则。因此,这个问题是相关的:检查用户是否已安装 Chrome 扩展程序

然而,在 Firefox 中目前有一些最好的方法是不可用的

文件将通过类似以下 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
      }
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接