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

如何在React网页应用中通过Chrome扩展获取浏览器窗口标签页列表?

Chrome扩展Popup与React页面通信获取标签页列表方案

场景1:React页面是Chrome扩展的一部分(如选项页、自定义页面)

这种情况直接用Chrome扩展的chrome.runtime消息API或者chrome.storage实现通信,步骤如下:

1. 配置Manifest.json(V3版本)

确保添加必要权限,并声明Popup和React页面:

{
  "manifest_version": 3,
  "name": "Tab Sync Tool",
  "version": "1.0",
  "permissions": ["tabs", "storage"],
  "action": {
    "default_popup": "popup.html"
  },
  // 假设React打包后的页面作为扩展选项页
  "options_page": "react-build/index.html"
}

2. Popup侧代码(popup.js)

Popup获取标签页后,可选择主动推送给React页面,或监听请求返回数据:

document.addEventListener('DOMContentLoaded', async () => {
  // 获取所有窗口的标签页数据
  const allTabs = await chrome.tabs.query({});

  // 方式一:主动推送给已打开的React页面
  const reactTabs = await chrome.tabs.query({ url: chrome.runtime.getURL('react-build/index.html') });
  if (reactTabs.length > 0) {
    chrome.tabs.sendMessage(reactTabs[0].id, { type: 'TAB_LIST', data: allTabs });
  }

  // 方式二:监听React页面的请求,返回标签页数据
  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.type === 'GET_TABS') {
      sendResponse({ tabs: allTabs });
      return true; // 异步响应需返回true保持通道开放
    }
  });

  // 方式三:存储到localStorage,供React页面随时读取(推荐持久化场景)
  await chrome.storage.local.set({ tabList: allTabs });
});

3. React页面侧代码(App.js)

根据Popup的通信方式,选择对应接收逻辑:

import { useEffect, useState } from 'react';

function App() {
  const [tabList, setTabList] = useState([]);

  useEffect(() => {
    // 方式一:监听Popup主动推送的消息
    const handlePushMessage = (message) => {
      if (message.type === 'TAB_LIST') {
        setTabList(message.data);
      }
    };
    chrome.runtime.onMessage.addListener(handlePushMessage);

    // 方式二:主动向Popup请求标签页数据
    const fetchTabs = async () => {
      try {
        const response = await chrome.runtime.sendMessage({ type: 'GET_TABS' });
        if (response?.tabs) setTabList(response.tabs);
      } catch (err) {
        console.error('获取标签页失败:', err);
      }
    };
    fetchTabs();

    // 方式三:从chrome.storage读取持久化的标签页数据
    const fetchFromStorage = async () => {
      const storageData = await chrome.storage.local.get('tabList');
      if (storageData.tabList) setTabList(storageData.tabList);
    };
    // fetchFromStorage(); // 取消注释启用此方式

    // 清理监听
    return () => {
      chrome.runtime.onMessage.removeListener(handlePushMessage);
    };
  }, []);

  return (
    <div className="App">
      <h1>所有标签页列表</h1>
      <ul>
        {tabList.map(tab => (
          <li key={tab.id}>
            <a href={tab.url} target="_blank" rel="noopener noreferrer">{tab.title}</a>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

场景2:React页面是外部网页(非扩展内页面)

这种情况需要通过Content Script作为中转层,实现扩展与外部网页的通信:

1. 更新Manifest.json

添加Content Script配置,指定匹配的React网页URL:

{
  "manifest_version": 3,
  "name": "Tab Sync Tool",
  "version": "1.0",
  "permissions": ["tabs", "storage"],
  "action": {
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": ["https://your-react-app-domain.com/*"], // 替换为你的React网页URL
      "js": ["content-script.js"]
    }
  ]
}

2. Content Script代码(content-script.js)

作为中间层转发消息:

// 接收Popup的消息,转发给外部React页面
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'TAB_LIST') {
    window.postMessage({ type: 'EXTENSION_TAB_DATA', data: message.data }, '*');
  }
});

// 接收外部React页面的请求,转发给Popup
window.addEventListener('message', (event) => {
  if (event.source !== window) return;
  if (event.data.type === 'REQUEST_TAB_DATA') {
    chrome.runtime.sendMessage({ type: 'GET_TABS' }, (response) => {
      window.postMessage({ type: 'EXTENSION_TAB_DATA', data: response.tabs }, '*');
    });
  }
});

3. 外部React页面代码(App.js)

通过window.postMessage与Content Script通信:

import { useEffect, useState } from 'react';

function App() {
  const [tabList, setTabList] = useState([]);

  useEffect(() => {
    const handleMessage = (event) => {
      if (event.data.type === 'EXTENSION_TAB_DATA') {
        setTabList(event.data.data);
      }
    };
    window.addEventListener('message', handleMessage);

    // 主动向扩展请求标签页数据
    window.postMessage({ type: 'REQUEST_TAB_DATA' }, '*');

    return () => {
      window.removeEventListener('message', handleMessage);
    };
  }, []);

  return (
    <div className="App">
      <h1>来自Chrome扩展的标签页列表</h1>
      <ul>
        {tabList.map(tab => (
          <li key={tab.id}>
            <a href={tab.url} target="_blank" rel="noopener noreferrer">{tab.title}</a>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

关键注意事项

  • 确保Manifest.json中已声明"tabs"权限,否则无法调用chrome.tabs.query。
  • Popup是临时页面,关闭后脚本会终止,若需持久化数据,优先使用chrome.storage.local。
  • 外部网页通信时,Content Script的matches规则必须匹配React网页的URL,否则无法注入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:47:13