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

部分网站脚本注入执行JavaScript失败:React脚本遇Babel未定义报错

解决Chase/Bank of America网站注入React时Babel未定义的问题

这种情况我之前在处理金融类网站脚本注入时也碰到过!核心原因在于Chase、Bank of America这类高安全等级的网站,会通过严格的内容安全策略(CSP)、全局变量隔离机制或者沙箱环境,阻止你访问加载完成的Babel全局对象——哪怕网络请求显示Babel脚本已经下载完成,它的变量也不会挂载到你能访问的window对象上。

下面给你几个可行的解决方案:

1. 绑定Babel加载回调,在上下文内执行转换

不要分开加载Babel再单独调用Babel.transform,而是把转换逻辑放在Babel脚本的onload回调里,确保在Babel的加载上下文里能直接访问到它的变量:

function injectScript(src, onLoaded) {
  const scriptTag = document.createElement('script');
  scriptTag.src = src;
  scriptTag.onload = onLoaded;
  scriptTag.async = false; // 确保脚本按顺序加载
  document.head.appendChild(scriptTag);
}

// 先加载React和ReactDOM,再加载Babel执行转换
injectScript('https://unpkg.com/react@18/umd/react.production.min.js', () => {
  injectScript('https://unpkg.com/react-dom@18/umd/react-dom.production.min.js', () => {
    injectScript('https://unpkg.com/@babel/standalone/babel.min.js', () => {
      // 在这里Babel是可访问的
      const jsxContent = `
        const MyComponent = () => <div>Inject React Component</div>;
        ReactDOM.render(<MyComponent />, document.body.appendChild(document.createElement('div')));
      `;
      const transformedCode = Babel.transform(jsxContent, {
        presets: ['react']
      }).code;

      // 注入转换后的代码
      const execScript = document.createElement('script');
      execScript.textContent = transformedCode;
      document.head.appendChild(execScript);
    });
  });
});

这种方式能绕过变量隔离,因为回调函数是在Babel脚本加载完成的上下文里执行的,能直接拿到Babel对象。

2. 避开Babel,直接使用React JSX Runtime

现在React官方支持直接使用JSX Runtime,不需要依赖Babel做在线转换。你可以直接引入相关的runtime模块,手动调用JSX函数来创建元素:

function injectScript(src, onLoaded) {
  const scriptTag = document.createElement('script');
  scriptTag.src = src;
  scriptTag.onload = onLoaded;
  document.head.appendChild(scriptTag);
}

// 按顺序加载依赖
injectScript('https://unpkg.com/react@18/umd/react.production.min.js', () => {
  injectScript('https://unpkg.com/react-dom@18/umd/react-dom.production.min.js', () => {
    injectScript('https://unpkg.com/@babel/runtime@7/umd/helpers.min.js', () => {
      // 使用babelHelpers.jsx创建JSX元素
      const { jsx } = window.babelHelpers;
      
      const MyComponent = () => jsx('div', null, 'Hello from injected React!');
      
      // 创建挂载容器并渲染
      const mountContainer = document.createElement('div');
      document.body.appendChild(mountContainer);
      const root = ReactDOM.createRoot(mountContainer);
      root.render(jsx(MyComponent, null));
    });
  });
});

这种方式完全不需要Babel的全局变量,能完美避开网站的隔离限制,同时也更轻量化。

3. 额外注意:网站的DOM保护机制

有些银行网站会通过MutationObserver监听DOM变化,自动移除未经允许的注入元素。所以你可能需要:

  • 找到页面上原本存在的、允许修改的容器(比如某个侧边栏空白div)来挂载你的React应用
  • 或者给注入的容器添加特殊的类名/属性,避免被网站的清理逻辑识别

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:12:47