javascript如何判断浏览器是否安装某插件


如需转载请标明出处:http://blog.csdn.net/itas109
QQ技术交流群:129518033

环境:

chrome: 90

1. 检测扩展的可访问资源【推荐】

原理:使用扩展可以访问的资源,确定扩展是否安装或启用

存在问题:需要知道extension id

以下 HTML 标签支持 onload :

<body>, <frame>, <frameset>, <iframe>, <img>, <input type="image">, <link>, <script>, <style>
  • 加载图片资源【推荐】

manifest.json

{
...
"web_accessible_resources": ["img/logo.png"]
}
function detectExtension(extensionId, callback) {
    let img;
    img = new Image();
    img.src = "chrome-extension://" + extensionId + "/img/logo.png";
    img.onload = function () {
        callback(true);
    };
    img.onerror = function () {
        callback(false);
    };
}

  • 加载配置json文件【不推荐】

manifest.json

通过 web_accessible_resources,列出资源,可经网页访问

{
...
"web_accessible_resources": ["manifest.json"]
}
function detectExtension(extensionId, callback) {
    let res = document.createElement('script');
    res.src = 'chrome-extension://' + extensionId + '/manifest.json';
    document.body.appendChild(res);
    res.onload = function () {
        callback(true);
    };
    res.onerror = function () {
        callback(false);
    };
}

2. 发送消息给插件判断返回信息

原理:页面 js 向 chrome 插件的 background.js 传送消息判断返回信息

存在问题:需要解决externally_connectable网址匹配问题

manifest.json

externally_connectable 属性声明哪些扩展程序、应用和网页可以通过 runtime.connect 和 runtime.sendMessage 连接到您的扩展程序

{
...

"externally_connectable": {
        "matches": [
            "*://localhost/*"
          ]
    },
}

background.js(content.js无效)

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

页面js

try {
    // 向指定id插件的 backgrond.js 发送消息
    chrome.runtime.sendMessage(pluginId, {
        message: "hasExtension"
    }, res => {
        if (res && res.hasExtension) {
            console.log('扩展存在');
        }
    })
} catch (error) {
    console.log(error.message);
    console.log("扩展未启用或不存在");
}

3. 插件修改页面源代码,写入插件标识,js检测标识

原理:尽管content script的执行环境与所在的页面是隔离的,但它们还是共享了页面的DOM。如果页面需要与content script通信(或者通过content script与扩展通信), 就必须通过这个共享的DOM。

存在问题:插件安装或卸载后,需要刷新页面才能生效

index.html

<!DOCTYPE html>
<html>

<body>
    <input id="ExtensionCheck" style="visibility: hidden"></input>

    <script>
        function test() {
            let div = document.getElementById("myapp-extension-installed-div");
            if (div) {
                console.log('扩展存在');
            } else {
                console.log('扩展未启用或不存在');
            }
        }
    </script>
</body>

content_script.js

'use strict';

let div = document.createElement('div');
div.setAttribute('id', 'my-extension-installed-div');
document.getElementsByTagName('body')[0].appendChild(div);

4. window.postMessage发送消息

使用 window.postMessage(或者 window.webkitPostMessage 用于可传输(Transferable)的对象)

在html中监听,content_script.js中发送消息

5. 通过共享资源方式

原理:通过共享资源方式,如cookie

存在问题:在插件卸载后,没有删除cookie会影响结果判断

index.html

if (document.cookie.indexOf('my_extension_installed') != -1){
    console.log('扩展存在');
}else{
    console.log('扩展未启用或不存在');
}

content_script.js

'use strict';

document.cookie = "my_extension_installed=true";

5. NavigatorPlugins.plugins

返回一个 PluginArray (en-US) 类型的对象, 包含了当前所使用的浏览器安装的所有插件

注意:该方法只能返回浏览器安装的内置插件

Plug-in NameFilenameDescription
Chrome PDF Plugininternal-pdf-viewerPortable Document Format
Chrome PDF Viewermhjfbmdgcfjbbpaeojofohoefgiehjai
Native Clientinternal-nacl-plugin

License

License under CC BY-NC-ND 4.0: 署名-非商业使用-禁止演绎


Reference:
NULL

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐