You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Chrome扩展弹窗关闭时仍能通过Socket.io显示通知

解决方案:独立于弹窗状态的Chrome扩展通知实现

核心思路是把Socket.io的连接和通知逻辑移到background脚本中——因为background脚本是Chrome扩展的后台常驻逻辑(Manifest V3为Service Worker,V2为持久后台页面),不受弹窗打开/关闭状态影响,能持续接收Socket.io消息并触发系统通知。

以下是适配你现有目录结构的分步实现:

1. 配置Manifest权限与后台脚本

修改public/manifest.json,确保注册background脚本并申请必要权限:

{
  "manifest_version": 3,
  "name": "你的扩展名称",
  "version": "1.0",
  "permissions": ["notifications", "storage"],
  "host_permissions": ["https://你的Socket.io服务器地址/*"], // 替换为实际服务器地址
  "background": {
    "service_worker": "/static/js/background.js" // 对应打包后的background脚本路径
  },
  "action": {
    "default_popup": "index.html" // React打包后的弹窗入口
  },
  "icons": {
    "48": "/icons/icon-48.png" // 需在public/icons下放对应图标,可选
  }
}

如果你用Manifest V2,将background字段改为:

"background": {
  "scripts": ["/static/js/background.js"],
  "persistent": true
}

2. 在background.js中实现Socket.io监听与通知逻辑

编辑src/background.js,初始化Socket.io连接并处理通知触发:

// 先安装socket.io-client依赖:npm install socket.io-client
import { io } from "socket.io-client";

// 连接Socket.io服务器
const socket = io("https://你的Socket.io服务器地址");

// 监听服务器推送的通知事件
socket.on("notification", (notifyData) => {
  // 创建Chrome系统通知
  chrome.notifications.create({
    type: "basic",
    iconUrl: "/icons/icon-48.png", // 对应public下的图标路径
    title: notifyData.title,
    message: notifyData.content,
    priority: 2 // 高优先级确保通知能被用户看到
  }, (notifyId) => {
    // 可选:将通知存入storage,供弹窗查看历史
    chrome.storage.local.set({ [notifyId]: notifyData });
  });
});

// 可选:监听通知点击事件,点击后打开弹窗
chrome.notifications.onClicked.addListener(() => {
  chrome.action.openPopup();
});

3. 配置React打包多入口(关键)

默认Create React App只打包主入口,需要配置多入口将background.js单独打包。这里用craco修改webpack配置:

  1. 安装依赖:
npm install @craco/craco --save-dev
  1. 在项目根目录创建craco.config.js:
module.exports = {
  webpack: {
    configure: (config) => {
      // 添加background入口
      config.entry = {
        main: config.entry,
        background: "./src/background.js"
      };
      // 修改输出文件名,避免与主入口冲突
      config.output.filename = "static/js/[name].js";
      return config;
    }
  }
};
  1. 修改package.json中的启动/打包脚本:
"scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test"
}

4. 弹窗页面同步通知历史(可选)

如果需要在弹窗中显示通知历史,可在React组件中从chrome.storage.local读取:

import { useEffect, useState } from "react";

function Popup() {
  const [notifyHistory, setNotifyHistory] = useState([]);

  useEffect(() => {
    // 读取所有已存储的通知
    chrome.storage.local.get(null, (items) => {
      setNotifyHistory(Object.values(items).reverse());
    });
  }, []);

  return (
    <div className="popup">
      <h3>通知历史</h3>
      {notifyHistory.map((item, idx) => (
        <div key={idx} className="notify-item">
          <h4>{item.title}</h4>
          <p>{item.content}</p>
        </div>
      ))}
    </div>
  );
}

export default Popup;

注意事项

  • Socket.io服务器地址必须加入host_permissions,否则会被Chrome的CSP策略拦截。
  • Service Worker(Manifest V3)是事件驱动的,若连接断开需实现重连逻辑,可在socket.on("disconnect")中添加重连代码。
  • 图标需使用扩展内的本地资源,不能用外部URL。

内容的提问来源于stack exchange,提问作者Forggy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:31:29