基于React的Manifest V3版Chrome扩展:如何传递DOM文本至App.js
问题场景
使用React开发Manifest V3版本的Chrome扩展,需求是从维基百科页面(示例URL:https://en.wikipedia.org/wiki/Erasmus_Sch%C3%B6fer)通过选择器#firstHeading获取标题文本,在扩展弹窗中展示。目前已在contentScript.js中实现文本获取并打印到控制台,但不清楚如何将文本传递至React的App.js文件。
已完成的代码及文件夹结构如下:
manifest.json
{ "name": "Wiki Title", "version": "0.01", "description": "grab page content", "action": { "default_popup": "popup.html" }, "content_scripts": [ { "matches": [ "<all_urls>" ], "js": [ "./scripts/contentScript.js" ], "run_at": "document_end" } ], "manifest_version": 3, "permissions": [ "tabs", "activeTab" ] }
contentScript.js
if (window.location.href.includes("wikipedia.com")) { let articleTitle = document.querySelector("#firstHeading"); if (typeof articleTitle != "undefined" && articleTitle != null) { const articleTitle = document.querySelector( "#firstHeading" ).innerText; console.log(articleTitle); } }
文件夹结构
项目根目录包含:
manifest.jsonpopup.htmlsrc文件夹(存放React相关文件,如App.js)scripts文件夹(存放contentScript.js)
解决方案
推荐两种常用的消息传递方式,根据需求选择:
方式一:Popup主动向Content Script请求数据(最常用)
当用户打开扩展弹窗时,Popup主动向当前活跃标签的Content Script发送请求,获取维基百科标题。
1. 修改contentScript.js,添加消息监听
// scripts/contentScript.js // 监听来自Popup的消息请求 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { // 判断请求类型 if (request.action === "getWikiTitle") { if (window.location.href.includes("wikipedia.org")) { // 安全获取标题文本 const articleTitle = document.querySelector("#firstHeading")?.innerText; // 返回结果给Popup sendResponse({ title: articleTitle || "未找到页面标题" }); } else { sendResponse({ title: "当前页面不是维基百科页面" }); } } });
2. 在React的App.js中发送请求并接收数据
// src/App.js import { useEffect, useState } from 'react'; function App() { const [wikiTitle, setWikiTitle] = useState(''); useEffect(() => { // 获取当前活跃的标签页 chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { const activeTab = tabs[0]; // 向Content Script发送请求 chrome.tabs.sendMessage(activeTab.id, { action: "getWikiTitle" }, (response) => { if (response?.title) { setWikiTitle(response.title); } }); }); }, []); return ( <div className="App"> <h2>维基百科页面标题</h2> <p>{wikiTitle}</p> </div> ); } export default App;
方式二:Content Script主动存储数据,Popup读取
如果需要页面加载时就获取标题并保存,后续打开Popup直接读取,可以使用Chrome本地存储API。
1. 修改contentScript.js,存储标题到本地
// scripts/contentScript.js if (window.location.href.includes("wikipedia.org")) { const articleTitle = document.querySelector("#firstHeading")?.innerText; if (articleTitle) { // 将标题存储到Chrome本地存储 chrome.storage.local.set({ wikiTitle: articleTitle }); } }
2. 在React的App.js中读取存储的数据
// src/App.js import { useEffect, useState } from 'react'; function App() { const [wikiTitle, setWikiTitle] = useState(''); useEffect(() => { // 从本地存储读取标题 chrome.storage.local.get('wikiTitle', (result) => { setWikiTitle(result.wikiTitle || "暂无标题数据"); }); }, []); return ( <div className="App"> <h2>维基百科页面标题</h2> <p>{wikiTitle}</p> </div> ); } export default App;
注意事项
- 优化Content Script的匹配范围:将
manifest.json中content_scripts的matches改为"https://*.wikipedia.org/*",避免在非维基百科页面注入脚本。 - 处理异步逻辑:Chrome API多为回调式,可根据需求封装为Promise简化代码。
- 权限检查:确保
manifest.json的permissions包含"tabs"、"activeTab"(方式一需要)或"storage"(方式二需要)。
内容的提问来源于stack exchange,提问作者Ava Juan
相关产品推荐
相关产品推荐

