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

React中使用WebWorker处理RSA密钥生成等耗时任务避免页面假死

React生成RSA密钥避免页面假死解决方案

核心思路是将CPU密集型的密钥生成任务完全放到Web Worker线程执行,不占用主线程的渲染、交互资源,你现有方案的方向正确,只需要修正以下问题即可:


1. 修正Web Worker代码

首先单独创建Worker文件 src/workers/rsaGenerator.worker.js,代码如下:

// 不需要export default,直接绑定Worker全局的onmessage事件
import NodeRSA from 'node-rsa';

self.onmessage = function() {
  // 需生成2048位则修改参数b为2048,原有代码写的是4096位
  const keysPair = new NodeRSA({ b: 2048 });
  const pubKey = keysPair.exportKey('public').replace(/(\r\n|\n|\r)/gm,"");
  const privKey = keysPair.exportKey('private');
  self.postMessage({
    pubKey,
    privKey
  });
  // 任务完成后关闭Worker释放资源
  self.close();
}

2. 修正React组件内的Worker调用逻辑

先根据你的构建工具导入Worker:

  • Vite项目导入方式:
// 组件顶部导入,注意后缀加?worker
import RsaKeyWorker from './workers/rsaGenerator.worker.js?worker';
  • CRA(create-react-app)项目导入方式:
// 组件顶部导入
const RsaKeyWorker = require('./workers/rsaGenerator.worker.js');

修正useEffect逻辑,增加异常处理、资源销毁、就绪通知:

// 提前申请系统通知权限,用于生成完成后通知用户
useEffect(() => {
  if (Notification.permission === 'default') {
    Notification.requestPermission();
  }
}, []);

useEffect(() => {
  const keysWorker = new RsaKeyWorker();
  keysWorker.postMessage("start");

  keysWorker.onmessage = (e) => {
    setPrivKey(e.data.privKey);
    setPubKey(e.data.pubKey);
    setKeyStatus('密钥生成完成,可下载!');
    setGenState(1);
    // 触发桌面就绪通知
    if (Notification.permission === 'granted') {
      new Notification('密钥生成完成', {
        body: '您的RSA密钥对已生成,可以下载私钥后进入平台'
      });
    }
  };

  // 监听Worker报错
  keysWorker.onerror = (error) => {
    console.error('密钥生成失败', error);
    setKeyStatus('密钥生成失败,请刷新页面重试');
  };

  // 组件卸载时销毁Worker,避免内存泄漏
  return () => {
    keysWorker.terminate();
  };
}, []);

3. 可选优化:用浏览器原生Web Crypto API提升性能

如果觉得NodeRSA依赖较重,可以替换为浏览器原生加密API生成密钥,性能提升30%以上,不需要额外引入第三方依赖,Worker代码修改为:

self.onmessage = async function() {
  // 生成2048位RSA密钥对
  const keyPair = await crypto.subtle.generateKey(
    {
      name: "RSA-OAEP",
      modulusLength: 2048,
      publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
      hash: "SHA-256"
    },
    true,
    ["encrypt", "decrypt"]
  );
  // 导出公钥并格式化
  const pubKeyBuffer = await crypto.subtle.exportKey("spki", keyPair.publicKey);
  const pubKey = btoa(String.fromCharCode(...new Uint8Array(pubKeyBuffer)));
  // 导出私钥并格式化
  const privKeyBuffer = await crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
  const privKey = `-----BEGIN PRIVATE KEY-----\n${btoa(String.fromCharCode(...new Uint8Array(privKeyBuffer))).match(/.{1,64}/g).join('\n')}\n-----END PRIVATE KEY-----`;
  
  self.postMessage({ pubKey, privKey });
  self.close();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:51:01