代码之家  ›  专栏  ›  技术社区  ›  11teenth

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

  •  1
  • 11teenth  · 技术社区  · 6 年前

    我希望我的Chrome扩展与一个包含一些简单的反作用组件的页面交互——在很多普通JavaScript /HTML中间的一个表。

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

    您可以通过Chrome扩展向页面中注入什么脚本来访问React元素(获取它们的键值和类似值)?一个简单的例子对我很有帮助。。。

    以下是我到目前为止所做的:

    我可以插入脚本并附加到页面主体。。。但我不确定如何“导入react”或以其他方式利用页面上的react代码。

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

    我怎样才能得到那个元素的子元素?例如,他们的关键价值观?

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

    import React from 'react';
    import ReactDOM from 'react-dom';
    

    我尝试了以下的变体(在我的注入脚本中):。。。没有发现任何反应(我知道它在那里)。。。“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;
        };
    

    感谢您的帮助/指导。

    1 回复  |  直到 6 年前
        1
  •  4
  •   11teenth    6 年前

    这篇帖子很有帮助: React - getting a component from a DOM element for debugging .尤其是React 16的答案更新。

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

    以下是我如何注入脚本来访问事物的反应面:

    在舱单上。json:

    "web_accessible_resources": [
        "scripts/yourScript.js"
    ],
    

    在现有内容脚本中(可能由某个事件或目标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);
    

    然后是一个新剧本,你的剧本。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);
    

    这至少会将React对象返回到控制台。。。我相信我可以用它做一些有用的事情:)