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

Chrome扩展开发:如何从React页面获取reactInstance?

解决Chrome扩展中使用findReact函数抓取React页面数据的问题

我之前做Chrome扩展抓取React站点数据时,也踩过类似的坑,结合你的场景,咱们一步步拆解问题和可行的解决办法:

一、先排查核心问题:React内部属性的版本变化

你提到的__reactInternalInstance是React早期版本的内部属性,但从React 16开始,官方为了避免外部依赖内部实现,对这些属性做了混淆处理:

  • 属性名会带上随机后缀,比如变成__reactInternalInstance$abc123
  • 后续版本甚至改用了__reactFiber$xxx作为Fiber节点的标识

如果Steemit-More-Info扩展里的findReact函数是针对旧版React写的,自然会失效。

二、修改findReact函数适配新版本React

可以把原函数改成匹配带后缀的内部属性,同时兼容Fiber节点:

function findReact(domElement) {
  // 查找React内部实例或Fiber节点的属性
  const reactKey = Object.keys(domElement).find(key => 
    key.startsWith('__reactInternalInstance$') || key.startsWith('__reactFiber$')
  );
  return reactKey ? domElement[reactKey] : null;
}

三、从Fiber节点中提取组件数据

拿到Fiber节点后,它可能只是DOM对应的叶子节点,需要向上遍历Fiber树找到包含业务数据的组件实例:

function getTargetComponent(fiberNode) {
  let currentFiber = fiberNode;
  // 向上遍历,直到找到包含props/state的组件节点
  while (currentFiber) {
    if (currentFiber.stateNode && typeof currentFiber.stateNode === 'object') {
      return currentFiber.stateNode;
    }
    currentFiber = currentFiber.return;
  }
  return null;
}

// 使用示例
const walletDom = document.querySelector('.UserWallet');
const reactFiber = findReact(walletDom);
const walletComponent = getTargetComponent(reactFiber);

// 类组件可直接访问state/props
if (walletComponent.state) {
  console.log('钱包状态:', walletComponent.state);
}
// 函数组件的状态存在memoizedState中,需根据实际结构解析
if (walletComponent.memoizedState) {
  console.log('函数组件状态:', walletComponent.memoizedState);
}

四、解决Chrome扩展上下文隔离问题

如果你的扩展是在内容脚本上下文运行,直接访问DOM的React内部属性会有问题——内容脚本和主页面的JS对象是隔离的。这时候需要把查找代码注入到主页面上下文:

// 内容脚本中执行
chrome.scripting.executeScript({
  target: { tabId: chrome.devtools.inspectedWindow.tabId },
  func: () => {
    const walletDom = document.querySelector('.UserWallet');
    const reactKey = Object.keys(walletDom).find(key => 
      key.startsWith('__reactInternalInstance$') || key.startsWith('__reactFiber$')
    );
    const fiber = reactKey ? walletDom[reactKey] : null;
    
    let currentFiber = fiber;
    while (currentFiber) {
      if (currentFiber.stateNode?.props) {
        // 提取你需要的具体数据,比如余额、地址
        return {
          balance: currentFiber.stateNode.props.balance,
          walletAddress: currentFiber.stateNode.props.address
        };
      }
      currentFiber = currentFiber.return;
    }
    return null;
  }
}, (results) => {
  if (results[0].result) {
    console.log('抓取到的钱包数据:', results[0].result);
    // 在这里处理拿到的数据
  }
});

最后提醒

依赖React内部属性是不稳定的方案,官方随时可能修改内部实现。如果目标网站有公开API,优先调用API获取数据;如果没有,再用这种方法,同时要做好不同React版本的兼容测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:24:06