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

Chrome扩展Manifest V3:service_worker与content_scripts如何通信?

解决方案

核心思路

利用扩展上下文(service_worker + content_script)的原生消息通信能力,结合页面上下文与content_script的自定义事件桥接,无需额外scripting权限即可实现数据交互:


1. 配置Manifest V3

确保manifest.json中已正确声明content_script的匹配规则,无需额外权限(仅需目标音乐网站的host权限):

{
  "manifest_version": 3,
  "name": "你的扩展名称",
  "version": "1.0",
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["*://*.你的音乐服务域名.com/*"],
      "js": ["content.js"]
    }
  ]
}

2. Content Script 实现(content.js)

负责在扩展上下文和页面上下文之间搭桥:

// 监听来自service_worker的曲目请求
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.type === 'GET_CURRENT_TRACK') {
    // 向页面上下文发送自定义事件,请求曲目信息
    const getTrackEvent = new CustomEvent('extension-get-track', { detail: {} });
    window.dispatchEvent(getTrackEvent);

    // 监听页面返回的曲目信息
    const handleTrackResponse = (e) => {
      window.removeEventListener('extension-send-track', handleTrackResponse);
      // 将数据回传给service_worker
      sendResponse(e.detail);
    };
    window.addEventListener('extension-send-track', handleTrackResponse);

    // 告知Chrome等待异步响应
    return true;
  }
});

// 可选:如果曲目信息直接在content_script中维护(比如你通过content_script调用音乐API)
// 可跳过页面通信步骤,直接返回缓存数据
// let currentTrack = null;
// chrome.runtime.onMessage.addListener((req, sender, sendRes) => {
//   if (req.type === 'GET_CURRENT_TRACK') sendRes(currentTrack);
// });

3. 页面上下文脚本注入(若曲目信息在页面侧)

如果音乐服务的曲目逻辑在页面上下文(而非content_script),通过content_script动态插入脚本实现通信:

// 在content.js中添加这段代码,注入页面脚本
const script = document.createElement('script');
script.textContent = `
// 监听来自content_script的曲目请求
window.addEventListener('extension-get-track', () => {
  // 根据音乐服务的DOM或API获取当前曲目信息
  const currentTrack = {
    title: document.querySelector('.track-title').textContent,
    artist: document.querySelector('.track-artist').textContent
    // 补充其他需要的字段
  };
  // 将数据回传给content_script
  const sendTrackEvent = new CustomEvent('extension-send-track', { detail: currentTrack });
  window.dispatchEvent(sendTrackEvent);
});
`;
document.head.appendChild(script);
script.remove();

4. Service Worker 实现(background.js)

当WebSocket收到Twitch请求时,向对应标签页的content_script发起查询:

// 建立Twitch WebSocket连接
const twitchWs = new WebSocket('wss://irc-ws.chat.twitch.tv');

twitchWs.onmessage = (event) => {
  const message = event.data;
  // 判断是否为获取曲目信息的指令
  if (message.includes('!gettrack')) {
    // 查找音乐服务所在的标签页
    chrome.tabs.query({ url: "*://*.你的音乐服务域名.com/*" }, (tabs) => {
      if (tabs.length > 0) {
        const musicTab = tabs[0];
        // 向content_script发送请求
        chrome.tabs.sendMessage(musicTab.id, { type: 'GET_CURRENT_TRACK' }, (response) => {
          if (response) {
            // 将曲目信息发送回Twitch聊天
            twitchWs.send(`PRIVMSG #你的频道名 :当前播放: ${response.title} - ${response.artist}`);
          } else {
            twitchWs.send(`PRIVMSG #你的频道名 :无法获取当前曲目信息`);
          }
        });
      } else {
        twitchWs.send(`PRIVMSG #你的频道名 :未打开音乐服务页面`);
      }
    });
  }
};

关键说明

  • 无额外权限依赖:通过content_script动态插入页面脚本替代chrome.scripting.executeScript,无需申请scripting权限
  • 规避CSP问题:WebSocket保留在service_worker中运行,Manifest V3默认CSP允许ws/wss协议连接,无需修改CSP规则
  • 原生通信保障:chrome.runtime.onMessage和chrome.tabs.sendMessage是Manifest V3原生API,无需额外权限即可在service_worker与content_script间通信

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 16:47:05