How to check if a Firefox WebExtension is installed or not with page JavaScript?

我只是一个虾纸丫 提交于 2019-12-12 13:34:08

问题


I have developed a WebExtension for Firefox and my website works with the extension as a prerequisite. I need to check programmatically whether the extension is installed or not and if not ask the user to install it.

I am not able to find a way how to check this operation of whether my extension is already installed in the user's browser.

Editor note: Methods available in Firefox differ from those available in Chrome, so this question is not a duplicate.


回答1:


Important note to begin with: A page can't query if an extension is installed without explicit help from the extension. This is done to prevent browser fingerprinting and/or preventing sites from denying content if certain extensions are installed.

WebExtensions are largely built upon the same principles as Chrome extensions. As such, this question is relevant: Check whether user has a Chrome extension installed.

However, some of the best methods available in Chrome are currently unavailable in Firefox:

  • You can't use external messaging from a webpage (through externally_connectable) as it's not available in FF.

  • You can't 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.

As such, what are your options? The page can't talk directly to the extension context (background), and the background can't directly affect the page; you need a Content script to interact with the page content.

How can page code and a content script communicate? They are isolated from each other unless content script does something about it.

First off, generic tricks that work in both FF and 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.

There are interesting Firefox-specific approaches as well:

  • 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
    }
    


来源:https://stackoverflow.com/questions/46727370/how-to-check-if-a-firefox-webextension-is-installed-or-not-with-page-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!