Javascript 检查用户是否安装了 Chrome 扩展
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6293498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check whether user has a Chrome extension installed
提问by BJury
I am in the process of building a Chrome extension, and for the whole thing to work the way I would like it to, I need an external JavaScript script to be able to detect if a user has my extension installed.
我正在构建 Chrome 扩展程序,为了让整个事情按照我希望的方式工作,我需要一个外部 JavaScript 脚本来检测用户是否安装了我的扩展程序。
For example: A user installs my plugin, then goes to a website with my script on it. The website detects that my extension is installed and updates the page accordingly.
例如:用户安装了我的插件,然后访问带有我的脚本的网站。该网站检测到我的扩展程序已安装并相应地更新页面。
Is this possible?
这可能吗?
采纳答案by Brad
I am sure there is a direct way (calling functions on your extension directly, or by using the JS classes for extensions), but an indirect method (until something better comes along):
我确定有一种直接的方法(直接调用扩展上的函数,或使用 JS 类进行扩展),但有一种间接方法(直到出现更好的方法):
Have your Chrome extension look for a specific DIV or other element on your page, with a very specific ID.
让您的 Chrome 扩展程序在您的页面上查找具有非常特定 ID 的特定 DIV 或其他元素。
For example:
例如:
<div id="ExtensionCheck_JamesEggersAwesomeExtension"></div>
Do a getElementById
and set the innerHTML
to the version number of your extension or something. You can then read the contents of that client-side.
执行 agetElementById
并将 设置为innerHTML
扩展程序的版本号或其他内容。然后您可以阅读该客户端的内容。
Again though, you should use a direct method if there is one available.
尽管如此,如果有可用的方法,您应该使用直接方法。
EDIT: Direct method found!!
编辑:找到直接方法!!
Use the connection methods found here: https://developer.chrome.com/extensions/extension#global-events
使用此处找到的连接方法:https: //developer.chrome.com/extensions/extension#global-events
Untested, but you should be able to do...
未经测试,但你应该能够做到......
var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);
回答by BJury
Chrome now has the ability to send messages from the website to the extension.
Chrome 现在能够从网站向扩展程序发送消息。
So in the extension background.js (content.js will not work) add something like:
所以在扩展 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;
});
This will then let you make a call from the website:
这将让您从网站拨打电话:
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;
}
});
You can then check the hasExtension variable. The only drawback is the call is asynchronous, so you have to work around that somehow.
然后您可以检查 hasExtension 变量。唯一的缺点是调用是异步的,所以你必须以某种方式解决这个问题。
Edit: As mentioned below, you'll need to add an entry to the manifest.jsonlisting the domains that can message your addon. Eg:
编辑:如下所述,您需要在manifest.json 中添加一个条目,列出可以向您的插件发送消息的域。例如:
"externally_connectable": {
"matches": ["*://localhost/*", "*://your.domain.com/*"]
},
回答by Xan
Another method is to expose a web-accessible resource, though this will allow any website to test if your extension is installed.
另一种方法是公开一个可通过网络访问的资源,尽管这将允许任何网站测试您的扩展是否已安装。
Suppose your extension's ID is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
, and you add a file (say, a transparent pixel image) as test.png
in your extension's files.
假设您的扩展程序的 ID 是aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
,并且您test.png
在扩展程序的文件中添加了一个文件(例如,透明像素图像)。
Then, you expose this file to the web pages with web_accessible_resources
manifest key:
然后,您使用web_accessible_resources
清单键将此文件公开给网页:
"web_accessible_resources": [
"test.png"
],
In your web page, you can try to load this file by its full URL (in an <img>
tag, via XHR, or in any other way):
在您的网页中,您可以尝试通过其完整 URL(在<img>
标签中、通过 XHR 或任何其他方式)加载此文件:
chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/test.png
If the file loads, then the extension is installed. If there's an error while loading this file, then the extension is not installed.
如果文件加载,则安装扩展。如果加载此文件时出现错误,则未安装扩展。
// 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);
};
}
Of note: if there is an error while loading this file, said network stackerror will appear in the console with no possibility to silence it. When Chromecast used this method, it caused quite a bit of controversybecause of this; with the eventual very ugly solution of simply blacklisting very specific errorsfrom Dev Tools altogether by the Chrome team.
注意:如果加载此文件时出现错误,所述网络堆栈错误将出现在控制台中,并且无法将其静音。Chromecast在使用这种方式的时候,也因此引起了不小的争议;最终非常丑陋的解决方案是由 Chrome 团队将开发工具中的非常具体的错误完全列入黑名单。
Important note:this method will not work in Firefox WebExtensions. Web-accessible resources inherently expose the extension to fingerprinting, since the URL is predictable by knowing the ID. Firefox decided to close that hole by assigning an instance-specific random URLto web accessible resources:
重要提示:此方法在 Firefox WebExtensions 中不起作用。Web 可访问资源固有地将扩展暴露给指纹,因为 URL 可以通过知道 ID 来预测。Firefox 决定通过为 Web 可访问资源分配一个特定于实例的随机 URL来弥补这个漏洞:
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.
然后可以使用如下 URL 访问这些文件:
moz-extension://<random-UUID>/<path/to/resource>
此 UUID 是为每个浏览器实例随机生成的,不是您的扩展程序的 ID。这可以防止网站对用户安装的扩展程序进行指纹识别。
However, while the extension can use runtime.getURL()
to obtain this address, you can't hard-code it in your website.
但是,虽然扩展程序可用于runtime.getURL()
获取此地址,但您不能在您的网站中对其进行硬编码。
回答by Nato
I thought I would share my research on this. I needed to be able to detect if a specific extension was installed for some file:/// links to work. I came across this article hereThis explained a method of getting the manifest.json of an extension.
我想我会分享我对此的研究。我需要能够检测是否为某些 file:/// 链接安装了特定的扩展。我在这里看到了这篇文章 这解释了一种获取扩展的 manifest.json 的方法。
I adjusted the code a bit and came up with:
我稍微调整了代码并提出:
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'); };
}
With this you should be able to use Ext_Detect(ExtensionName,ExtensionID) to detect the installation of any number of extensions.
有了这个,您应该能够使用 Ext_Detect(ExtensionName,ExtensionID) 来检测任意数量的扩展的安装。
回答by PAEz
Another possible solution if you own the website is to use inline installation.
如果您拥有该网站,另一种可能的解决方案是使用内联安装。
if (chrome.app.isInstalled) {
// extension is installed.
}
I know this an old question but this way was introduced in Chrome 15 and so I thought Id list it for anyone only now looking for an answer.
我知道这是一个老问题,但这种方式是在 Chrome 15 中引入的,所以我认为我只为现在正在寻找答案的任何人列出它。
回答by Chase Roberts
I used the cookie method:
我使用了 cookie 方法:
In my manifest.js file I included a content script that only runs on my site:
在我的 manifest.js 文件中,我包含了一个仅在我的网站上运行的内容脚本:
"content_scripts": [
{
"matches": [
"*://*.mysite.co/*"
],
"js": ["js/mysite.js"],
"run_at": "document_idle"
}
],
in my js/mysite.js I have one line:
在我的 js/mysite.js 我有一行:
document.cookie = "extension_downloaded=True";
and in my index.html page I look for that cookie.
在我的 index.html 页面中,我寻找那个 cookie。
if (document.cookie.indexOf('extension_downloaded') != -1){
document.getElementById('install-btn').style.display = 'none';
}
回答by Niklas
You could have the extension set a cookieand have your websites JavaScript check if that cookie is present and update accordingly. This and probably most other methods mentioned here could of course be cirvumvented by the user, unlessyou try and have the extension create custom cookies depending on timestamps etc, and have your application analyze them server side to see if it really is a user with the extension or someone pretending to have it by modifying his cookies.
您可以让扩展程序设置一个 cookie,并让您的网站 JavaScript 检查该 cookie 是否存在并相应地更新。这也可能是最等方法这里所说的当然可以由用户cirvumvented,除非你尝试的扩展创造取决于时间戳等自定义Cookie,并让您的应用程序进行分析服务器端,看它是否真的是用户与扩展名或某人通过修改他的 cookie 假装拥有它。
回答by Beau
There's another method shown at this Google Groups post. In short, you could try detecting whether the extension icon loads successfully. This may be helpful if the extension you're checking for isn't your own.
此 Google Groups 帖子 中显示了另一种方法。总之,您可以尝试检测扩展图标是否加载成功。如果您要检查的扩展程序不是您自己的,这可能会有所帮助。
回答by Fox32
Your extension could interact with the website (e.g. changing variables) and your website could detect this.
您的扩展程序可以与网站交互(例如更改变量),您的网站可以检测到这一点。
But there should be a better way to do this. I wonder how Google is doing it on their extension gallery (already installed applications are marked).
但是应该有更好的方法来做到这一点。我想知道谷歌是如何在他们的扩展库上做到这一点的(已经安装的应用程序被标记)。
Edit:
编辑:
The gallery use the chrome.management.getfunction. Example:
图库使用chrome.management.get函数。例子:
chrome.management.get("mblbciejcodpealifnhfjbdlkedplodp", function(a){console.log(a);});
But you can only access the method from pages with the right permissions.
但是您只能从具有正确权限的页面访问该方法。
回答by Dawid Szymański
Webpage interacts with extension through background script.
网页通过后台脚本与扩展交互。
manifest.json:
清单.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:
页面.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>