Подтвердить что ты не робот

Проверьте, установлено ли у пользователя расширение Chrome

Я занимаюсь созданием расширения Chrome, и для того, чтобы все работало так, как мне бы хотелось, мне нужен внешний JavaScript script, чтобы узнать, установлен ли пользователь для моего расширения.

Например: пользователь устанавливает мой плагин, а затем переходит на сайт с моим script. Веб-сайт обнаруживает, что мое расширение установлено и обновляет страницу соответственно.

Возможно ли это?

4b9b3361

Ответ 1

Я уверен, что есть прямой способ (вызывающие функции на вашем расширении напрямую или с использованием классов JS для расширений), но косвенный метод (пока не появится что-то лучшее):

У вашего расширения Chrome найдите определенный DIV или другой элемент на вашей странице с очень конкретным идентификатором.

Например:

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

Сделайте getElementById и установите innerHTML номер версии вашего расширения или что-то еще. Затем вы можете прочитать содержимое этой клиентской стороны.

Опять же, вы должны использовать прямой метод, если есть один доступный.


EDIT: найден найденный прямой метод

Используйте методы соединения, найденные здесь: https://developer.chrome.com/extensions/extension#global-events

Неподтвержденный, но вы должны быть в состоянии сделать...

var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);

Ответ 2

Теперь Chrome имеет возможность отправлять сообщения с веб-сайта на расширение.

Итак, в расширении background.js(content.js не будет работать) добавьте что-то вроде:

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

Это позволит вам сделать звонок с веб-сайта:

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;
        }
    });

Затем вы можете проверить переменную hasExtension. Единственный недостаток - вызов асинхронный, поэтому вам нужно как-то обойти это.

Изменить: Как уже упоминалось ниже, вам нужно добавить запись в manifest.json, в которой перечислены домены, которые могут сообщать ваш аддон. Например:

"externally_connectable": {
    "matches": ["*://localhost/*", "*://your.domain.com/*"]
},

Ответ 3

Другим методом является предоставить ресурс, доступный в Интернете, хотя это позволит любому веб-сайту проверить, установлено ли ваше расширение.

Предположим, что ваш идентификатор расширения aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, и вы добавляете файл (скажем, прозрачное пиксельное изображение) как test.png в ваши файлы расширений.

Затем вы открываете этот файл на веб-страницах с помощью web_accessible_resources манифеста:

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

На своей веб-странице вы можете попробовать загрузить этот файл по его полному URL-адресу (в теге <img> через XHR или любым другим способом):

chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/test.png

Если файл загружен, добавляется расширение. Если при загрузке этого файла произошла ошибка, расширение не установлено.

// 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); 
  };
}
Примечание: если при загрузке файла произошла ошибка, указанная ошибка сетевого стека появится в консоли без возможности ее отключения. Из-за этого, когда Chromecast использовал этот метод, вызвал немало споров; с возможным очень уродливым решением просто черного списка очень специфических ошибок из Dev Tools в целом командой Chrome.

Важное примечание: этот метод не будет работать в Firefox WebExtensions. Ресурсы, доступные через Интернет, по своей сути предоставляют расширение для отпечатков пальцев, поскольку URL-адрес предсказуем, зная идентификатор. Firefox решил закрыть эту дыру присвоение произвольного URL-адреса, специфичного для экземпляра, доступным ресурсам сети:

Затем файлы будут доступны с использованием URL-адреса, например:

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

Этот UUID генерируется случайным образом для каждого экземпляра браузера и не является вашим идентификатором расширения. Это не позволяет веб-сайтам отпечатывать расширения, которые пользователь установил.

Однако, хотя расширение может использовать runtime.getURL() для получения этого адреса, вы не можете жестко записать его на своем веб-сайте.

Ответ 4

Я думал, что поделюсь своими исследованиями по этому вопросу. Мне нужно было иметь возможность определить, установлено ли конкретное расширение для какого-либо файла:///ссылки на работу. Я наткнулся на эту статью здесь. Здесь объясняется метод получения файла manifest.json для расширения.

Я немного подкорректировал код и придумал:

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'); };
}

При этом вы сможете использовать Ext_Detect (ExtensionName, ExtensionID) для обнаружения установки любого количества расширений.

Ответ 5

Другим возможным решением, если вы являетесь владельцем веб-сайта, является использование встроенной установки .

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

Я знаю, что это старый вопрос, но этот способ был введен в Chrome 15, и поэтому я думал, что Id перечисляет его для всех, только теперь ищет ответ.

Ответ 6

Ваше расширение может взаимодействовать с веб-сайтом (например, изменять переменные), и ваш сайт может обнаружить это.

Но должен быть лучший способ сделать это. Интересно, как Google делает это в своей галерее расширения (уже установленные приложения отмечены).

Edit:

В галерее используется функция chrome.management.get. Пример:

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

Но вы можете получить доступ только к этому методу со страниц с правильными разрешениями.

Ответ 7

У вас может быть расширение установить файл cookie, и ваши сайты JavaScript проверяют, присутствует ли этот файл cookie и соответствующим образом обновляется. Этот и, возможно, большинство других методов, упомянутых здесь, могут, конечно, быть вызваны пользователем, , если вы не попробуете, и у вас есть расширение, создающее пользовательские файлы cookie в зависимости от временных меток и т.д., И попросите ваше приложение проанализировать их на стороне сервера, чтобы узнать, это действительно пользователь с расширением или кто-то притворяется, что он может изменить его файлы cookie.

Ответ 8

Здесь показан еще один способ, показанный на этой странице Google Groups. Короче говоря, вы можете попытаться определить, успешно ли загружается значок расширения. Это может быть полезно, если расширение, которое вы проверяете, не является вашим собственным.

Ответ 9

Я использовал метод cookie:

В моем файле manifest.js я включил контент script, который работает только на моем сайте:

 "content_scripts": [
        {
        "matches": [
            "*://*.mysite.co/*"
            ],
        "js": ["js/mysite.js"],
        "run_at": "document_idle"
        }
    ], 

в моей js/mysite.js У меня есть одна строка:

document.cookie = "extension_downloaded=True";

и на моей странице index.html я ищу этот файл cookie.

if (document.cookie.indexOf('extension_downloaded') != -1){
    document.getElementById('install-btn').style.display = 'none';
}

Ответ 10

Веб-страница взаимодействует с расширением через фон script.

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});
    }
});

page.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>

Ответ 11

Пока что здесь есть ответы только на Chrome или наложение HTTP-накладных расходов. Решение, которое мы используем, немного отличается:

1. Добавьте новый объект в список манифеста content_scripts следующим образом:

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

Это позволит выполнить код в файле install_notifier.js на этом сайте (если у вас там еще не было разрешений).

2. Отправьте сообщение каждому сайту в манифест-ключе выше.

Добавьте что-то вроде этого в install_notifier.js (обратите внимание, что здесь используется замыкание, чтобы переменные не были глобальными, но в этом нет особой необходимости):

// Dispatch a message to every URL that 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
  }, "*");
})();

Ваше сообщение может сказать что угодно, но полезно отправить версию, чтобы вы знали, с чем имеете дело. Затем...

3. На вашем сайте прослушайте это сообщение.

Добавьте это на свой сайт где-нибудь:

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");
  }
});

Это работает в Firefox и Chrome и не требует HTTP-накладных расходов или манипулирования страницей.

Ответ 12

Если у вас есть контроль над расширением Chrome, вы можете попробовать, что я сделал:

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

И затем:

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

}

Он немного взломан, но я не мог заставить другие методы работать, и я беспокоюсь о том, что Chrome меняет свой API здесь. Сомнительно, что этот метод скоро перестанет работать.

Ответ 13

Вы также можете использовать метод кросс-браузера, который я использовал. Использует концепцию добавления div.

в вашем контенте script (всякий раз, когда загружается script, он должен это делать)

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

на вашем сайте вы утверждаете что-то вроде

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

И отправьте соответствующее сообщение.

Ответ 14

Если вы пытаетесь обнаружить какое-либо расширение с любого веб-сайта, это сообщение помогло: https://ide.hey.network/post/5c3b6c7aa7af38479accc0c7

По сути, решением было бы просто попытаться получить конкретный файл (manifest.json или изображение) из расширения, указав его путь. Вот что я использовал. Определенно работает:

const imgExists = function(_f, _cb) {
    const __i = new Image();
    __i.onload = function() {
        if (typeof _cb === 'function') {
            _cb(true);
        }
    }
    __i.onerror = function() {
        if (typeof _cb === 'function') {
            _cb(false);
        }
    }
    __i.src = _f;
    __i = null;
});

try {
    imgExists("chrome-extension://${CHROME_XT_ID}/xt_content/assets/logo.png", function(_test) {
        console.log(_test ? 'chrome extension installed !' : 'chrome extension not installed..');
        ifrm.xt_chrome = _test;
        // use that information
    });
} catch (e) {
    console.log('ERROR', e)
}