Как проверить, установлен ли Firefox WebExtension на странице JavaScript или нет?

Я разработал WebExtension для Firefox, и мой веб-сайт работает с расширением в качестве предварительного условия. Мне нужно программно проверить, установлено ли расширение или нет, и если нет, попросить пользователя установить его.

Я не могу найти способ проверить, работает ли мое расширение в браузере пользователя.

Примечание редактора: методы, доступные в Firefox, отличаются от методов, доступных в Chrome, поэтому этот вопрос не является дубликатом.

1 ответ

Решение

Важное примечание для начала: страница не может запрашивать, если расширение установлено без явной помощи от расширения. Это делается для предотвращения дактилоскопии в браузере и / или предотвращения запрета содержимого сайтами, если установлены определенные расширения.

WebExtensions в основном построены на тех же принципах, что и расширения Chrome. Таким образом, этот вопрос актуален: проверьте, установлено ли у пользователя расширение Chrome.

Однако некоторые из лучших методов, доступных в Chrome, в настоящее время недоступны в Firefox:

Как таковой, каковы ваши варианты? Страница не может напрямую взаимодействовать с контекстом расширения (фоном), а фон не может напрямую влиять на страницу; вам нужен контент-скрипт для взаимодействия с контентом страницы.

Как может взаимодействовать код страницы и скрипт контента? Они изолированы друг от друга, если контентный скрипт ничего не делает с этим.

Прежде всего, общие приемы, которые работают как в FF, так и в Chrome:

  • Вы можете создать или изменить элемент DOM на странице из сценария содержимого и посмотреть эти изменения на странице.

    // 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 чтобы общаться между контекстами, хотя это неуклюже использовать в качестве двунаправленного канала.

    Вот документация и пример 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
      }
    });
    
  • Вы можете использовать пользовательские события DOM аналогичным образом.

Также есть интересные подходы, специфичные для Firefox:

  • Вы можете поделиться кодом со страницей, используя 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
    }
    
Другие вопросы по тегам