chrome插件实时通信的几种方式

chrome插件开发中我们知道,background.js是独立于浏览器的,在background.js中主要负责popupcontent.js的交互,在某些时候,也许你需要在一个插件的设置页与content进行实时通信,此时你能想到什么样的方式吗?本文是在插件业务通信总结的一篇笔记,希望看完能在实际业务中带来思考和帮助

正文开始...

在插件通信中,我们先从backgroundpopupcontent中来一起重温那些常用的通信交互

background.js

chrome.runtime.onMessage.addListener监听content.js发送过来的消息

js 复制代码
// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  const { type } = request;
  console.log(request)
  if (type === "open_set_page") {
    // 打开设置页
    chrome.runtime.openOptionsPage();
  }
})

content.js

content.js中,使用chrome.runtime.sendMessage(params),当我们在content.js点击设置按钮时,此时就会打开设置页,此时会触发backrgound.js

js 复制代码
// content.js
const setBtnDom = document.getElementById("set");
setBtnDom.onclick = function () {
    // 向background.js传入消息
    chrome.runtime.sendMessage({
      type: "open_set_page",
    });
};

设置页与background.js通信

我们在content.js中打开了一个设置页,此时如果设置页向与content进行通信,那么该怎么办呢?

我们尝试在设置页background.js中发送消息

js 复制代码
 document.getElementById("light").onclick = function () {
    console.log("light");
    // changeTheme,向background发送消息
    chrome.runtime.sendMessage({ type: "changeTheme", theme: "light" });
  };

我们会发现backrgound.js中接收到了来自set页面的信息

js 复制代码
// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  const { type } = request;
  // 打开设置页面
  if (type == "open_set_page") {
    chrome.runtime.openOptionsPage();
  }
  if (type === "changeTheme") {
    console.log(request, "=request");
  }
});

在一个插件的内部页面与content实时通信

比如现在有个场景,我在设置页需要设置content页面的主题,而且需要实时修改,那么怎么办呢?

主要利用chrome.tabs.querychrome.tabs.sendMessage这两个api实现

js 复制代码
  // set.js
  function sendMessageToActiveTab(message) {
    // 获取当前活动标签
    chrome.tabs.query({}, function (tabs) {
      tabs
        .filter((v) => v.active)
        .forEach((v) => {
          chrome.tabs.sendMessage(v.id, message);
        });
    });
  }
  let flag = true;
  document.getElementById("dark").onclick = function () {
    flag = !flag;
    sendMessageToActiveTab({ action: "buttonClicked", theme: flag ? "dark" : "light" });
  };

content.js中我们监听set.js发送过来的消息

js 复制代码
const textDom = document.getElementById("text");
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  console.log(sender.id, chrome.runtime.id);
   const {theme} = request;
   textDom.style.color = theme === 'dark' ? "black": "red"
});

此时你会发现当你在设置点击按钮操作时,当前激活的tab就会实时触发

但是有一个场景,就是我想修改所有的content的状态,那该怎么办呢?

其实我们只需要修改一行代码即可

js 复制代码
 function sendMessageToActiveTab(message) {
    // 向所有的tabde
    chrome.tabs.query({}, function (tabs) {
      tabs
        .forEach((v) => {
          chrome.tabs.sendMessage(v.id, message);
        });
    });
  }

缓存

当你在设置页修改状态时,content确实是可以实时变化了,但是,当你刷新,当前的状态的就会改变,所以你需要如何保持当前状态,那么你需要用到插件的缓存功能

在使用缓存功能之前,你需要在permission中添加storage

json 复制代码
{
   "permissions": ["storage"]
}

在插件的设置页面

js 复制代码
  // set.js
  let flag = true;
  document.getElementById("dark").onclick = function () {
    flag = !flag;
    // port.postMessage({ type: "changeTheme", theme: "dark" });
    const theme = flag ? "dark" : "light";
    sendMessageToActiveTab({
      action: "buttonClicked",
      theme,
    });
    chrome.storage.local.set({ theme });
  };

content.js

js 复制代码
// content.js
chrome.storage.local.get("theme", function (result) {
  console.log(result, "result");
  const { theme = "" } = result || { theme: "" };
  if (theme === "dark") {
    textDom.style.color = "black";
  } else {
    textDom.style.color = "red";
  }
});

当你在chrome设置页设置缓存时,你在content重新刷新,那么就可以正常的获取缓存了。

总结

  • 了解content.jsbackground.js的通信,或者是popupcontent的通信,借助chrome.runtime.sendMessage实现

  • 在插件的内部页面如何与其他页面通信,比如一个插件的设置页与content.js实时通信,我们是借助先查询所有的tabs,chrome.tabs.query({}, callback),然后再向所有的tabs发送消息chrome.tabs.sendMessage(id, data),最后在content.jschrome.runtime.onMessage监听发送过来的消息

  • code example

相关推荐
一个处女座的程序猿O(∩_∩)O1 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink4 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者6 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-6 小时前
验证码机制
前端·后端
燃先生._.7 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖8 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235248 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240259 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar9 小时前
纯前端实现更新检测
开发语言·前端·javascript