Sprawdź, czy użytkownik ma zainstalowane rozszerzenie Chrome

Jestem w trakcie budowania rozszerzenia Chrome i aby wszystko działało tak, jak bym chciał, potrzebuję zewnętrznego skryptu JavaScript, aby móc wykryć, czy użytkownik ma zainstalowane moje rozszerzenie.

Na przykład: użytkownik instaluje moją wtyczkę, a następnie przechodzi do strony internetowej z moim skryptem na niej. Witryna wykrywa, że moje rozszerzenie jest zainstalowane i odpowiednio aktualizuje stronę.

Czy to możliwe?

Author: Yehuda Katz, 2011-06-09

13 answers

Jestem pewien, że istnieje metoda bezpośrednia (wywołanie funkcji bezpośrednio na Twoim rozszerzeniu lub użycie klas JS dla rozszerzeń), ale metoda pośrednia (dopóki nie pojawi się coś lepszego):

Niech rozszerzenie Chrome poszukuje określonego DIV lub innego elementu na stronie, z bardzo określonym identyfikatorem.

Na przykład:

<div id="ExtensionCheck_JamesEggersAwesomeExtension"></div>

Wykonaj getElementById i ustaw innerHTML na numer wersji twojego rozszerzenia lub czegoś takiego. Możesz wtedy przeczytać treść tego po stronie klienta.

Ponownie jednak, należy użyć metody bezpośredniej, jeśli jest dostępna.


EDIT: metoda bezpośrednia znaleziona!!

Użyj metod połączenia, które znajdziesz tutaj: https://developer.chrome.com/extensions/extension#global-events

/ Align = "left" / ..
var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);
 39
Author: Brad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-22 18:58:15

Chrome ma teraz możliwość wysyłania wiadomości z witryny do rozszerzenia.

Więc w tle rozszerzenia.js (content.js nie zadziała) dodaj coś w stylu:

chrome.runtime.onMessageExternal.addListener(
    function(request, sender, sendResponse) {
        if (request) {
            if (request.message) {
                if (request.message == "version") {
                    sendResponse({version: 1.0});
                }
            }
        }
        return true;
    });

To pozwoli Ci wykonać Połączenie ze strony internetowej:

var hasExtension = false;

chrome.runtime.sendMessage(extensionId, { message: "version" },
    function (reply) {
        if (reply) {
            if (reply.version) {
                if (reply.version >= requiredVersion) {
                    hasExtension = true;
                }
            }
        }
        else {
          hasExtension = false;
        }
    });

Możesz następnie sprawdzić zmienną hasExtension. Jedyną wadą jest to, że połączenie jest asynchroniczne, więc musisz jakoś to obejść.

Edytuj: Jak wspomniano poniżej, musisz dodać wpis do manifestu .json lista domen, które mogą wysyłać wiadomości do twojego dodatku. Eg:

"externally_connectable": {
    "matches": ["*://localhost/*", "*://your.domain.com/*"]
},
 88
Author: BJury,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 04:16:12

Inną metodą jest ujawnienie zasobu dostępnego w sieci , chociaż pozwoli to każdej witrynie przetestować, czy Twoje rozszerzenie jest zainstalowane.

Załóżmy, że identyfikator rozszerzenia To aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa i dodajesz plik (powiedzmy przezroczysty obraz pikselowy) jako test.png w plikach rozszerzenia.

Następnie ujawniasz ten plik na stronach internetowych za pomocą web_accessible_resources klucza manifestu:

  "web_accessible_resources": [
    "test.png"
  ],

Na swojej stronie możesz spróbować załadować ten plik po pełnym adresie URL (w tagu <img>, przez XHR lub w dowolnym innym sposób):

chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/test.png

Jeżeli Plik się ładuje, wtedy rozszerzenie jest zainstalowane. Jeśli wystąpił błąd podczas ładowania tego pliku, rozszerzenie nie jest zainstalowane.

// Code from https://groups.google.com/a/chromium.org/d/msg/chromium-extensions/8ArcsWMBaM4/2GKwVOZm1qMJ
function detectExtension(extensionId, callback) { 
  var img; 
  img = new Image(); 
  img.src = "chrome-extension://" + extensionId + "/test.png"; 
  img.onload = function() { 
    callback(true); 
  }; 
  img.onerror = function() { 
    callback(false); 
  };
}

Uwaga: Jeśli wystąpi błąd podczas ładowania tego pliku, w konsoli pojawi się błąd stos sieciowy bez możliwości wyciszenia go. Kiedy Chromecast użył tej metody, to wywołało sporo kontrowersji z tego powodu; z ewentualnym bardzo brzydkim rozwiązaniem po prostu Czarna lista bardzo specyficzne błędy z narzędzi programistycznych autorstwa zespołu Chrome.


Ważna uwaga: ta metoda nie będzie działać w Firefox WebExtensions. Zasoby Dostępne w sieci z natury narażają rozszerzenie na odcisk palca, ponieważ adres URL jest przewidywalny dzięki znajomości identyfikatora. Firefox zdecydował się zamknąć tę dziurę przez przypisanie przypadkowego adresu URL do zasobów dostępnych w sieci:

Pliki będą następnie dostępne przy użyciu adresu URL, takiego jak:

moz-extension://<random-UUID>/<path/to/resource>

Ten UUID jest generowany losowo dla każdej instancji przeglądarki i nie jest identyfikatorem rozszerzenia. Uniemożliwia to witrynom pobieranie odcisków palców z rozszerzeń zainstalowanych przez użytkownika.

Jednak, podczas gdy rozszerzenie może użyć runtime.getURL(), aby uzyskać ten adres, nie możesz go kodować na swojej stronie internetowej.

 18
Author: Xan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-17 08:21:53

Pomyślałem, że podzielę się moimi badaniami na ten temat. Musiałem być w stanie wykryć, czy dla jakiegoś pliku zostało zainstalowane konkretne rozszerzenie:/// links to work. Natknąłem się na ten artykuł tutaj To wyjaśniło sposób uzyskania manifestu.json rozszerzenia.

Poprawiłem trochę kod i wymyśliłem:

   function Ext_Detect_NotInstalled(ExtName,ExtID) {
   console.log(ExtName + ' Not Installed');
   if (divAnnounce.innerHTML  != '')
   divAnnounce.innerHTML = divAnnounce.innerHTML + "<BR>"

   divAnnounce.innerHTML = divAnnounce.innerHTML + 'Page needs ' + ExtName + ' Extension -- to intall the LocalLinks extension click <a href="https://chrome.google.com/webstore/detail/locallinks/' + ExtID +'">here</a>';
  }

  function Ext_Detect_Installed(ExtName,ExtID) {
    console.log(ExtName + ' Installed');
  }

  var Ext_Detect = function(ExtName,ExtID) {
    var s = document.createElement('script');
    s.onload = function(){Ext_Detect_Installed(ExtName,ExtID);};
    s.onerror = function(){Ext_Detect_NotInstalled(ExtName,ExtID);};
    s.src = 'chrome-extension://' + ExtID + '/manifest.json';
    document.body.appendChild(s);
  }

 var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;

 if (is_chrome==true)
 {
  window.onload = function() { Ext_Detect('LocalLinks','jllpkdkcdjndhggodimiphkghogcpida');};
 }

Dzięki temu powinieneś być w stanie użyć Ext_Detect(ExtensionName,ExtensionID) do wykrycia instalacji dowolnej liczby rozszerzeń.

 17
Author: Nato,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-05 23:21:59

Innym możliwym rozwiązaniem, jeśli posiadasz stronę internetową, jest użycie inline installation.

if (chrome.app.isInstalled) {
  // extension is installed.
}

Wiem, że to stare pytanie, ale ten sposób został wprowadzony w Chrome 15, więc pomyślałem, że lista Id dla każdego, kto dopiero teraz szuka odpowiedzi.

 7
Author: PAEz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 16:52:19

Możesz mieć rozszerzenie ustawić plik cookie i mieć swoje strony internetowe JavaScript sprawdzić, czy ten plik cookie jest obecny i odpowiednio zaktualizować. Ta i prawdopodobnie większość innych metod wymienionych tutaj może być oczywiście cirvumventowana przez użytkownika, chyba że spróbujesz utworzyć niestandardowe pliki cookie w zależności od znaczników czasu itp., a Twoja aplikacja przeanalizuje je po stronie serwera, aby sprawdzić, czy naprawdę jest to użytkownik z rozszerzeniem lub ktoś, kto udaje, że go posiada, modyfikując swoje dane. ciasteczka.

 3
Author: Niklas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-09 13:47:44

Jest inna metoda pokazana na to Google Groups post . Krótko mówiąc, możesz spróbować sprawdzić, czy ikona rozszerzenia ładuje się pomyślnie. Może to być pomocne, jeśli rozszerzenie, którego szukasz, nie jest twoje.

 3
Author: Beau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-17 01:20:13

Użyłem metody cookie:

W moim manifeście.plik js dodałem skrypt zawartości, który działa tylko na mojej stronie:
 "content_scripts": [
        {
        "matches": [
            "*://*.mysite.co/*"
            ],
        "js": ["js/mysite.js"],
        "run_at": "document_idle"
        }
    ], 
W moim js/mysite.js mam jedną linijkę:
document.cookie = "extension_downloaded=True";

I w moim indeksie.strona html szukam tego ciastka.

if (document.cookie.indexOf('extension_downloaded') != -1){
    document.getElementById('install-btn').style.display = 'none';
}
 3
Author: Chase Roberts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 17:59:18

Strona internetowa współdziała z rozszerzeniem poprzez skrypt w tle.

Manifest.json:

"background": {
    "scripts": ["background.js"],
    "persistent": true
},
"externally_connectable": {
    "matches": ["*://(domain.ext)/*"]
},

background.js:
chrome.runtime.onMessageExternal.addListener(function(msg, sender, sendResponse) {
    if ((msg.action == "id") && (msg.value == id))
    {
        sendResponse({id : id});
    }
});

Strona.html:

<script>
var id = "some_ext_id";
chrome.runtime.sendMessage(id, {action: "id", value : id}, function(response) {
    if(response && (response.id == id)) //extension installed
    {
        console.log(response);
    }
    else //extension not installed
    {
        console.log("Please consider installig extension");
    }

});
</script>
 3
Author: Dawid Szymański,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 10:36:34

Twoje rozszerzenie może wchodzić w interakcje z witryną (np. zmieniając zmienne) i Twoja witryna może to wykryć.

Ale powinien być na to lepszy sposób. Ciekawe jak Google robi to na swojej galerii rozszerzeń(już zainstalowane aplikacje są oznaczone).

Edit:

Galeria używa chrome.zarządzanie.get function. Przykład:

chrome.management.get("mblbciejcodpealifnhfjbdlkedplodp", function(a){console.log(a);});

Ale dostęp do metody można uzyskać tylko ze stron z odpowiednimi uprawnieniami.

 3
Author: Fox32,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-14 20:18:40

Wiele odpowiedzi tutaj do tej pory są tylko Chrome lub ponieść karę HTTP overhead. Rozwiązanie, którego używamy, jest nieco inne:

1. Dodaj nowy obiekt do listy manifest content_scripts w następujący sposób:

{
  "matches": ["https://www.yoursite.com/*"],
  "js": [
    "install_notifier.js"
  ],
  "run_at": "document_idle"
}

Pozwoli to na użycie kodu w install_notifier.js do uruchomienia na tej stronie (jeśli nie masz jeszcze tam uprawnień).

2. Wyślij wiadomość do każdej witryny w powyższym kluczu manifestu.

Dodaj coś takiego do install_notifier.js (zauważ, że jest to użycie zamknięcia, aby zmienne nie były globalne, ale nie jest to bezwzględnie konieczne):

// Dispatch a message to every URL that's in the manifest to say that the extension is
// installed.  This allows webpages to take action based on the presence of the
// extension and its version. This is only allowed for a small whitelist of
// domains defined in the manifest.
(function () {
  let currentVersion = chrome.runtime.getManifest().version;
  window.postMessage({
    sender: "my-extension",
    message_name: "version",
    message: currentVersion
  }, "*");
})();

Twoja wiadomość może powiedzieć cokolwiek, ale warto wysłać wersję, abyś wiedział, z czym masz do czynienia. Więc...

3. Na swojej stronie, posłuchaj tej wiadomości.

Dodaj to gdzieś na swoją stronę:

window.addEventListener("message", function (event) {
  if (event.source == window &&
    event.data.sender &&
    event.data.sender === "my-extension" &&
    event.data.message_name &&
    event.data.message_name === "version") {
    console.log("Got the message");
  }
});

Działa to w Firefoksie i Chrome i nie powoduje narzutu HTTP ani nie manipuluje stroną.

 2
Author: mlissner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 15:49:47

Jeśli masz kontrolę nad rozszerzeniem Chrome, możesz spróbować tego, co zrobiłem:

// Inside Chrome extension
var div = document.createElement('div');
div.setAttribute('id', 'myapp-extension-installed-div');
document.getElementsByTagName('body')[0].appendChild(div);

A następnie:

// On web page that needs to detect extension
if ($('#myapp-extension-installed-div').length) {

}

Wydaje się to trochę trudne, ale nie mogłem uruchomić innych metod i martwię się, że Chrome zmieni swoje API tutaj. Wątpliwe, że ta metoda przestanie działać w najbliższym czasie.

 0
Author: gwg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-10 11:49:40

Możesz również użyć metody cross-browser, której użyłem. Używa koncepcji dodawania div.

W skrypcie zawartości (gdy skrypt się ładuje, powinien to zrobić)

if ((window.location.href).includes('*myurl/urlregex*')) {
        $('html').addClass('ifextension');
        }

Na swojej stronie twierdzisz coś w stylu:

if (!($('html').hasClass('ifextension')){}

I wrzucić odpowiednią wiadomość.

 0
Author: Prakash Palnati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-19 09:29:44