87 javascript google-chrome google-chrome-extension
我正在构建Chrome扩展程序,并且要按照我希望的方式工作,我需要一个外部JavaScript脚本来检测用户是否安装了我的扩展程序.
例如:用户安装我的插件,然后转到我的脚本上的网站.该网站检测到我的扩展程序已安装并相应地更新页面.
这可能吗?
BJu*_*ury 105
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;
});
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过网站拨打电话:
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;
}
});
Run Code Online (Sandbox Code Playgroud)
然后,您可以检查hasExtension变量.唯一的缺点是调用是异步的,所以你必须以某种方式解决这个问题.
编辑:如下所述,您需要在manifest.json中添加一个条目,列出可以向您的插件发送消息的域.例如:
"externally_connectable": {
"matches": ["*://localhost/*", "*://your.domain.com/*"]
},
Run Code Online (Sandbox Code Playgroud)
Bra*_*rad 42
我确信有一种直接的方法(直接调用扩展中的函数,或者使用扩展的JS类),但是间接方法(直到更好的方式出现):
让您的Chrome扩展程序在页面上查找特定的DIV或其他元素,并使用非常具体的ID.
例如:
<div id="ExtensionCheck_JamesEggersAwesomeExtension"></div>
Run Code Online (Sandbox Code Playgroud)
执行a getElementById
并设置innerHTML
扩展名的版本号或其他内容.然后,您可以阅读该客户端的内容.
但是,如果有可用的话,你应该使用直接方法.
编辑:发现直接方法!
使用此处的连接方法:https: //developer.chrome.com/extensions/extension#global-events
未经测试,但你应该能够......
var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);
Run Code Online (Sandbox Code Playgroud)
Xan*_*Xan 19
另一种方法是公开Web可访问资源,但这将允许任何网站测试您的扩展是否已安装.
假设您的扩展程序的ID是aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
,并且您test.png
在扩展程序的文件中添加了一个文件(例如,透明像素图像).
然后,使用web_accessible_resources
清单键将此文件公开给网页:
"web_accessible_resources": [
"test.png"
],
Run Code Online (Sandbox Code Playgroud)
在您的网页中,您可以尝试通过其完整URL(在<img>
标记中,通过XHR或以任何其他方式)加载此文件:
chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/test.png
Run Code Online (Sandbox Code Playgroud)
如果文件加载,则安装扩展.如果加载此文件时出错,则表示未安装扩展程序.
// 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);
};
}
Run Code Online (Sandbox Code Playgroud)
值得注意的是:如果加载此文件时出错,则表示网络堆栈错误将出现在控制台中,不可能使其静音.当Chromecast使用这种方法时,由于这个原因引起了相当多的争议 ; 最简单的解决方案是将Chrome团队完全将Dev Tools中的特定错误列入黑名单.
重要说明:此方法在Firefox WebExtensions中不起作用.Web可访问资源固有地将扩展名暴露给指纹识别,因为通过知道ID可以预测URL.Firefox决定通过为Web可访问资源分配特定于实例的随机URL来关闭该漏洞:
然后可以使用以下URL访问这些文件:
Run Code Online (Sandbox Code Playgroud)moz-extension://<random-UUID>/<path/to/resource>
此UUID是为每个浏览器实例随机生成的,不是您的扩展程序ID.这可以防止网站对用户安装的扩展名进行指纹识别.
但是,虽然扩展程序可用于runtime.getURL()
获取此地址,但您无法在网站中对其进行硬编码.
小智 18
我以为我会分享我对此的研究.我需要能够检测是否为某些文件安装了特定的扩展名:///链接工作.我在这里看到这篇文章 这解释了获取扩展的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'); };
}
Run Code Online (Sandbox Code Playgroud)
有了这个,您应该能够使用Ext_Detect(ExtensionName,ExtensionID)来检测任意数量的扩展的安装.
如果您拥有该网站,另一种可能的解决方案是使用内联安装.
if (chrome.app.isInstalled) {
// extension is installed.
}
Run Code Online (Sandbox Code Playgroud)
我知道这是一个老问题,但这种方式是在Chrome 15中引入的,因此我认为我列出的内容仅适用于现在正在寻找答案的人.
这是另一种现代方法:
const checkExtension = (id, src, callback) => {
let e = new Image()
e.src = 'chrome-extension://'+ id +'/'+ src
e.onload = () => callback(1), e.onerror = () => callback(0)
}
// "src" must be included to "web_accessible_resources" in manifest.json
checkExtension('gighmmpiobklfepjocnamgkkbiglidom', 'icons/icon24.png', (ok) => {
console.log('AdBlock: %s', ok ? 'installed' : 'not installed')
})
checkExtension('bhlhnicpbhignbdhedgjhgdocnmhomnp', 'images/checkmark-icon.png', (ok) => {
console.log('ColorZilla: %s', ok ? 'installed' : 'not installed')
})
Run Code Online (Sandbox Code Playgroud)
我使用了 cookie 方法:
在我的 manifest.js 文件中,我包含了一个仅在我的网站上运行的内容脚本:
"content_scripts": [
{
"matches": [
"*://*.mysite.co/*"
],
"js": ["js/mysite.js"],
"run_at": "document_idle"
}
],
Run Code Online (Sandbox Code Playgroud)
在我的 js/mysite.js 我有一行:
document.cookie = "extension_downloaded=True";
Run Code Online (Sandbox Code Playgroud)
在我的 index.html 页面中,我寻找那个 cookie。
if (document.cookie.indexOf('extension_downloaded') != -1){
document.getElementById('install-btn').style.display = 'none';
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
85051 次 |
最近记录: |