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

如何在React项目中不使用CDN全局暴露CryptoJS以支持外部非模块脚本调用

如何在React项目中不使用CDN全局暴露CryptoJS以支持外部非模块脚本调用

我来帮你搞定这个问题!要在React项目里不依赖CDN全局暴露CryptoJS,让index.html中的非模块脚本能安全调用它的加密函数,你可以按照以下步骤一步步操作:

1. 本地安装CryptoJS包

首先移除原来CDN的引入,改用包管理工具安装本地版本:

# npm
npm install crypto-js

# 或者yarn
yarn add crypto-js

2. 在React入口文件全局挂载CryptoJS

React的入口文件(通常是src/main.tsx或src/main.jsx)是ES模块,内部变量默认不会全局暴露。我们需要手动将CryptoJS挂载到window对象上,这样非模块脚本就能访问到它:

TypeScript版本(main.tsx)

import CryptoJS from 'crypto-js';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

// 全局暴露CryptoJS到window对象
// 如果你想获得类型提示,可以扩展Window接口(见下文可选优化)
(window as any).CryptoJS = CryptoJS;

// 正常渲染你的React应用
ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);

JavaScript版本(main.jsx)

import CryptoJS from 'crypto-js';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

// 直接挂载到window
window.CryptoJS = CryptoJS;

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);

可选:TypeScript类型优化(获得类型提示)

如果你用TypeScript,不想每次都用(window as any),可以扩展Window接口来添加CryptoJS的类型定义:
在src/types目录下创建crypto-js.d.ts文件:

import CryptoJS from 'crypto-js';

declare global {
  interface Window {
    CryptoJS: typeof CryptoJS;
  }
}

之后就可以直接用window.CryptoJS = CryptoJS,不用类型断言了。

3. 调整index.html中的非模块脚本

接下来修改index.html,移除CDN脚本,同时注意执行时机和语法错误(你原来的代码里有个scipt拼写错误,已经修正):

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Sample</title>
</head>
<body>
  <div id="root"></div>
  <!-- React模块脚本先加载,确保CryptoJS被挂载到window -->
  <script type="module" src="/src/main.tsx"></script>
  
  <!-- 非模块脚本放在React脚本之后,或用事件确保加载完成 -->
  <script>
    // 用DOMContentLoaded事件确保React和CryptoJS都已初始化完成
    window.addEventListener('DOMContentLoaded', () => {
      // 注意:请确保publicKey和salt变量在此处已存在
      // 如果这些变量来自React应用,你可能需要通过自定义事件/全局变量传递
      const keyBytes = CryptoJS.PBKDF2(
        publicKey,
        CryptoJS.enc.Hex.parse(
          Array.from(salt)
            .map((b) => b.toString(16).padStart(2, '0'))
            .join(''),
        ),
        {
          keySize: 12,
          iterations: 10000,
          hasher: CryptoJS.algo.SHA256,
        },
      );
      
      // 这里可以添加keyBytes的后续处理逻辑
      console.log('生成的密钥字节:', keyBytes);
    });
  </script>
</body>
</html>

关键注意事项

  • 执行时机:一定要确保非模块脚本在React入口脚本之后执行,或者用DOMContentLoaded事件监听,否则会出现CryptoJS is not defined的错误——因为React模块还没来得及把CryptoJS挂载到window上。
  • 变量传递:如果你的publicKey或salt是从React应用内部生成的,不能直接在非模块脚本中访问,需要通过全局变量或自定义事件来传递数据(比如在React中触发一个自定义事件,非模块脚本监听该事件并接收参数)。
  • 语法修正:你原来的代码里把script拼写成了scipt,这个小错误会导致脚本无法执行,已经在示例中修正。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:08:03