【JS】判断是否安装了某个Chrome插件

前提

manifest.json 清单

下文均以manifest.json v3介绍。

因为Chrome官方文档中明确说明,v2已经弃用了。

ID

由于浏览器的安全策略,以下方法均在「已知扩展程序 ID」 的前提下才可实现。

获取扩展程序ID

进入扩展程序管理页,找到对应插件。
注意:上架后的程序ID唯一,但是开发阶段(文件夹拖入形式),ID是随机变化的(每次拖入ID发生改变)。


方式一:Web端加载扩展程序中的资源

通过web端尝试加载扩展程序中的资源来判断是否下载了插件。

扩展程序

在manifest.json 清单中将图片暴露为 web可访问资源。

注意:一定要加后缀,按照编译器默认提示并不会生效。

Web端

通过扩展程序ID,尝试加载扩展程序中暴露的图片资源

javascript 复制代码
function detectExtension(extensionId) {
    let img
    img = new Image()
    img.src = "chrome-extension://" + extensionId + "/icons/logo-tini.png"
    img.onload = function () {
        console.log("插件已存在")
    };
    img.onerror = function () {
        console.log("未找到插件")
    };
}

方式二:Web与扩展程序通信

扩展程序

在manifest.json 清单中,添加externally_connectable配置项,该配置项用于指定扩展与哪些网站可以进行外部通信,即与网站的内容脚本进行通信。

background.js中监听Web端的消息

javascript 复制代码
// background.js
chrome.runtime.onMessageExternal.addListener(function (
  message,
  sender,
  sendResponse
) {
  if (message && message === "hasExtension") {
    sendResponse({ hasExtension: true })
  } else {
    return true
  }
})

但是content.js中不可以监听Web端的消息,主要因为 「沙盒环境限制」「消息传递机制」

沙盒环境限制

content.js在网页环境中运行,与网页的 DOM 共享同一个沙盒环境,但与扩展程序的其他部分(如 background.js)处于不同的沙盒环境 。因此,content.js 无法直接访问 Chrome 扩展 API,包括 chrome.runtime.onMessage.addListener。

消息传递机制

content.js 与其他部分通信的主要方式是通过消息传递。content.js 可以使用 chrome.runtime.sendMessage 方法向其他部分发送消息,其他部分可以通过监听 chrome.runtime.onMessage.addListener 来接收消息。但 content.js 自身不具备接收消息的能力,因为它运行在沙盒环境中,无法直接监听 Chrome 扩展的事件。

Web端

javascript 复制代码
try {
  chrome.runtime.sendMessage(
    extensionId,
    "hasExtension",
    (res) => {
      console.log("res", res)
      if (res && res.hasExtension) {
        console.log("插件已存在")
      }
    }
  )
} catch (error) {
  console.log(error.message)
  console.log("未找到插件")
}

方式三:扩展程序向Web端插入元素(不需要扩展程序ID,更适用于开发阶段未上架的扩展)

扩展程序

在 content.js 中向页面插入标识,也可以自行操作dom,比如给某个web端已存在的标签添加自定义属性等等。

javascript 复制代码
let div = document.createElement('div');
div.setAttribute('id', 'hasExtension');
// 也可以继续添加多个自定义属性用于提高健壮性
div.setAttribute("isInstalled", "true")
document.getElementsByTagName('body')[0].appendChild(div);

注意:一定要写在 content.js 中,其他不生效。因为只有 content.js 与Web端DOM共享一个沙盒环境。content.js 会在页面加载完成后注入到页面中,但是在页面的 DOM 元素加载完毕之前执行。

Web端

javascript 复制代码
function detectExtension() {
  let div = document.getElementById("hasExtension");
  let flag = div.getAttribute("isInstalled")
  if (div && flag) {
        console.log('插件已存在');
  } else {
      console.log('未找到插件');
  }
}
相关推荐
wuyk5553 分钟前
18.Kruskal 算法:用最短的边连成一张网
开发语言·算法·图论
Evand J3 分钟前
【MATLAB例程,图像降噪7】高斯加权滑动窗口滤波,用于图像降噪,带质量评价,附代码下载链接
开发语言·图像处理·matlab·滑动窗口·滤波·降噪·图像滤波
十年一梦惊觉醒13 分钟前
快手视频发布助手,全自动视频发布带货工具
开发语言·前端·javascript
Java后端的Ai之路13 分钟前
一文搞懂 GitHub Actions-CICD
开发语言·大模型·github·cicd·action
超人气王14 分钟前
细说agent心跳机制--agentLoop循环机制中死循环处理,带你进一步了解agent工作底层原理
javascript·人工智能
码匠许师傅16 分钟前
【C++三方组件】开篇总论:为什么需要以及如何选型?
开发语言·c++
cvby31 分钟前
C++11--右值引用和移动语义
开发语言·c++
dsyyyyy110142 分钟前
Typescript装饰器
前端·javascript·typescript
en.en..43 分钟前
TCP/UDP 收发流程(网络字节序---函数讲解)
开发语言·php
名字还没想好☜1 小时前
Go 用 json.Decoder 流式解析大 JSON:边读边处理不爆内存
开发语言·后端·golang·go·json