Chrome 扩展程序可以将什么脚本注入到页面中来访问 React 元素?

11t*_*nth 2 google-chrome-extension reactjs

我希望我的 Chrome 扩展能够与包含一些简单 React 组件的页面进行交互 - 一个位于大量纯 javascript/html 中间的表格。

我的扩展不是用 React 构建的。

您可以通过 Chrome 扩展将什么脚本注入到页面中,以访问 React Elements(获取其键值等)?一个简单的例子将极大地帮助我......

这是我到目前为止所做的:

我可以注入脚本并附加到页面正文...但不确定如何“导入反应”或以其他方式利用页面上的 React 代码。

使用控制台中的 React 检查器,我可以看到一个以行作为子元素的元素。

我如何获得该元素的子元素?例如,他们的关键价值观是什么?

如果我注入以下脚本,我只会收到“意外标识符”错误:

import React from 'react';
import ReactDOM from 'react-dom';
Run Code Online (Sandbox Code Playgroud)

我已经尝试了以下内容的变体(在我注入的脚本中)...没有找到 React(我知道它在那里)...记录了“Inside FindReact function...1”消息,但没有其他内容(所以我知道我的脚本注入没有错误)。

console.log('In React script...run sub...');
reactSub();

function reactSub(){
    console.log('Inside FindReact function...1');
    window.FindReact = function(dom) {
        for (var key in dom) {
                    console.log('Loooping...');
            if (key.startsWith("__reactInternalInstance$")) {
                var compInternals = dom[key]._currentElement;
                var compWrapper = compInternals._owner;
                var comp = compWrapper._instance;
                            console.log('Inside FindReact function...2') + console.log(comp);
                return comp;
            }
            let snapCount = React.Children.toArray(this.props.children).filter((item) => item.props.className === 'criterions').length;
            // let rubricTable = FindReact(document.querySelector('.criterions'));
            console.log('Inside react script...') + console.log(snapCount);
          }
        return null;
    };
Run Code Online (Sandbox Code Playgroud)

任何帮助/指导表示赞赏。

11t*_*nth 5

这篇文章非常有帮助:React - getting a component from a DOM element for debug。特别是 React 16 的答案更新。

我尝试的代码有很多问题......但它也(特别是var compInternals = dom[key]._currentElement;)仅在 React 15 及更早版本中工作。显然,我的目标页面使用 React 16。

以下是我如何注入脚本来访问 React 方面的内容:

在manifest.json中:

"web_accessible_resources": [
    "scripts/yourScript.js"
],
Run Code Online (Sandbox Code Playgroud)

在现有的内容脚本中(可能由某些事件或目标 React 组件的存在触发):

var th = document.getElementsByTagName('body')[0];
    var s = document.createElement('script');
    s.setAttribute('type', 'text/javascript');
    // s.setAttribute('src', file);
    s.setAttribute('src', 'chrome-extension://yourChromeEXTid/scripts/yourScript.js');
    th.appendChild(s);
Run Code Online (Sandbox Code Playgroud)

然后是一个新脚本 yourScript.js:

console.log('In React script...run sub...');

window.FindReact = function(el) {
  for (const key in el) {
        console.log(key);
    if (key.startsWith('__reactInternalInstance$')) {
      const fiberNode = el[key];
            console.log('fibernode: ') + console.log(fiberNode);
            return fiberNode;
      // return fiberNode && fiberNode.return && fiberNode.return.stateNode;
    }
  }
  return null;
};

var targetEl = document.querySelector('.targetReactElement');
var reactIs = FindReact(targetEl);
console.log('Result: ') + console.log(reactIs);
Run Code Online (Sandbox Code Playgroud)

这至少会向控制台返回 React 对象...我确信我可以用它做一些有用的事情:)