Проверьте, установлено ли расширение Chrome
Я нахожусь в процессе создания расширения Chrome, и для всего этого, чтобы работать так, как я хотел бы, мне нужен внешний скрипт JavaScript, чтобы иметь возможность определить, если пользователь имеет мое расширение установлено.
например: пользователь устанавливает мой плагин, затем переходит на веб-сайт с моим скриптом на нем. Веб-сайт обнаруживает, что мое расширение установлено и обновляет страницу соответствующим образом.
это возможно?
13 ответов
Я уверен, что есть прямой способ (вызов функций на вашем расширении напрямую или с помощью классов 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);
Chrome теперь имеет возможность отправлять сообщения с веб-сайта на расширение.
Итак, в фоновом режиме расширения.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. Единственным недостатком является асинхронный вызов, поэтому вам нужно как-то обойти это.
изменить: Как указано ниже, вам нужно добавить запись к манифест.в JSON список доменов, которые могут отправлять сообщения вашему аддону. Например:
"externally_connectable": {
"matches": ["*://localhost/*", "*://your.domain.com/*"]
},
другой метод -выставляем сетевой ресурс, хотя это позволит любому веб-сайту проверить, установлено ли ваше расширение.
предположим, что идентификатор вашего расширения 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()
получить этот адрес, вы не можете жестко закодировать его на свой сайт.
Я думал, что поделюсь своими исследованиями по этому вопросу. Мне нужно было определить, установлено ли определенное расширение для какого-либо файла:/// ссылки на работу. Я наткнулся на эту статью здесь Это объясняло метод получения манифеста.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) для обнаружения установки любого количества увеличение.
другое возможное решение, если вы владеете веб-сайтом, - использовать установка роликовых.
if (chrome.app.isInstalled) {
// extension is installed.
}
Я знаю, что это старый вопрос, но этот способ был введен в Chrome 15, и поэтому я думал, что Id перечислит его для тех, кто только сейчас ищет ответ.
У вас может быть расширение установить cookie и ваши веб-сайты JavaScript проверьте, присутствует ли этот файл cookie и обновите его соответствующим образом. Этот и, вероятно, большинство других методов, упомянутых здесь, конечно, могут быть cirvumvented пользователем,Если вы пытаетесь и имеете расширение создавать пользовательские куки в зависимости от временных меток и т. д., и ваше приложение анализирует их на стороне сервера, чтобы увидеть, действительно ли это пользователь с расширением или кто-то притворяется, что он изменение его печенья.
есть еще один метод, показанный в это сообщение Google групп. Короче говоря, вы можете попробовать определить, успешно ли загружается значок расширения. Это может быть полезно, если расширение вы проверяете не свои собственные.
я использовал метод cookie:
В моем манифесте.JS файл я включил скрипт контента, которая работает только на моем сайте:
"content_scripts": [
{
"matches": [
"*://*.mysite.co/*"
],
"js": ["js/mysite.js"],
"run_at": "document_idle"
}
],
в моем JS / mysite.js у меня одна строка:
document.cookie = "extension_downloaded=True";
и в мой индекс.html-страница я ищу этот файл cookie.
if (document.cookie.indexOf('extension_downloaded') != -1){
document.getElementById('install-btn').style.display = 'none';
}
Веб-страница взаимодействует с расширением через фоновый скрипт.
манифест.в 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});
}
});
страница.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>
расширения могут взаимодействовать с веб-сайтом (например, изменение переменных) и ваш сайт мог обнаружить это.
но должен быть лучший способ сделать это. Интересно, как Google делает это в своей галерее расширений (уже установленные приложения отмечены).
Edit:
галерея использовать chrome.управление.get. Пример:
chrome.management.get("mblbciejcodpealifnhfjbdlkedplodp", function(a){console.log(a);});
но вы можете получить доступ только к методу со страниц с правильные разрешения.
многие ответы здесь до сих пор только 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'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
}, "*");
})();
ваше сообщение может сказать что угодно, но полезно отправить версию, чтобы вы знали, с чем имеете дело. Затем...
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 или манипулировать страница.
Если у вас есть контроль над расширением 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 здесь. Сомнительно, что этот метод перестанет работать в ближайшее время.
вы также можете использовать кросс-браузерный метод, который я использовал. Использует концепцию добавления div.
в вашем скрипте содержимого (всякий раз, когда скрипт загружается, он должен это сделать)
if ((window.location.href).includes('*myurl/urlregex*')) {
$('html').addClass('ifextension');
}
в своем сайте Вы утверждаете что-то вроде
if (!($('html').hasClass('ifextension')){}
и выдать соответствующие сообщение.