Node.js前端调用依赖JS模块报错及适配问题咨询
解决方案
核心问题根源
你当前的核心矛盾是前端直接复用了后端的Crypto.js,但该文件依赖Node.js专属API(child_process、Node版本node-rsa),且浏览器模块系统与Node.js不兼容,导致一系列加载和运行错误。以下是针对性的解决步骤:
一、彻底分离前后端加密逻辑
前端无法运行Node.js专属模块,必须重构前端加密解密实现:
1. 前端替换为浏览器兼容的RSA方案
使用浏览器原生Web Crypto API(无需额外依赖,更安全),新建前端专属的Crypto.js:
// 前端Crypto.js - 仅适配浏览器环境 // 服务器公钥:预先从后端安全获取(示例直接内嵌,生产环境建议通过接口返回) const serverPublicKeyPem = `-----BEGIN PUBLIC KEY----- // 替换为你的服务器公钥内容 -----END PUBLIC KEY-----`; // 将PEM格式公钥转换为Web Crypto可识别的密钥对象 async function importServerPublicKey() { const pemContents = serverPublicKeyPem .replace("-----BEGIN PUBLIC KEY-----", "") .replace("-----END PUBLIC KEY-----", "") .replace(/\s/g, ""); const binaryDer = Uint8Array.from(atob(pemContents), c => c.charCodeAt(0)); return await window.crypto.subtle.importKey( "spki", binaryDer, { name: "RSA-OAEP", hash: "SHA-256" }, true, ["encrypt"] ); } // 用服务器公钥加密请求数据 export async function encryptForServer(message) { const key = await importServerPublicKey(); const encoder = new TextEncoder(); const encryptedBuffer = await window.crypto.subtle.encrypt( { name: "RSA-OAEP" }, key, encoder.encode(message) ); // 转换为base64字符串便于JSON传输 return btoa(String.fromCharCode(...new Uint8Array(encryptedBuffer))); } // 用前端私钥解密服务器响应(私钥需安全存储,禁止硬编码) export async function decryptFromServer(encryptedMessage) { const clientPrivateKeyPem = `-----BEGIN PRIVATE KEY----- // 替换为前端私钥内容(生产环境需通过安全方式获取) -----END PRIVATE KEY-----`; const pemContents = clientPrivateKeyPem .replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") .replace(/\s/g, ""); const binaryDer = Uint8Array.from(atob(pemContents), c => c.charCodeAt(0)); const key = await window.crypto.subtle.importKey( "pkcs8", binaryDer, { name: "RSA-OAEP", hash: "SHA-256" }, true, ["decrypt"] ); const encryptedBuffer = Uint8Array.from(atob(encryptedMessage), c => c.charCodeAt(0)); const decryptedBuffer = await window.crypto.subtle.decrypt( { name: "RSA-OAEP" }, key, encryptedBuffer ); return new TextDecoder().decode(decryptedBuffer); }
2. 修复后端Crypto.js的拼写错误
后端Crypto.js的Decrypt函数中存在拼写错误:ExecuteInTermianal应改为ExecuteInTerminal,否则会导致解密失败。
二、修复前端模块加载错误
1. 解决"Cannot use import statement outside a module"
保留<script type="module" src="connection.js"></script>的配置,这是浏览器支持ES模块的正确方式。
2. 解决"Failed to resolve module specifier 'module'"
删除前端所有代码中引用Node.js专属模块的语句(比如import { createRequire } from 'module';),确保前端代码只使用浏览器兼容的API。
三、调整前端connection.js适配新逻辑
修改connection.js调用新的前端加密函数,并正确处理响应:
import { encryptForServer, decryptFromServer } from './Crypto.js'; const btn1 = document.getElementById('btn1') btn1.addEventListener('click', post) async function post(e) { e.preventDefault(); // 用服务器公钥加密请求内容 const encryptedRequest = await encryptForServer('<Text>'); const data = JSON.stringify({request: encryptedRequest}); const res = await fetch('http://<IP>:<Port>/', { method: 'POST', headers: { "Content-Type": 'application/json', }, body: data }); const responseData = await res.json(); console.log('加密响应:', responseData); // 用前端私钥解密响应内容 const decryptedReply = await decryptFromServer(responseData.reply); console.log('解密后响应:', decryptedReply); }
四、额外安全注意事项
- 前端私钥绝对不能硬编码到代码中,生产环境需通过安全流程(如登录时后端加密返回、前端存储在IndexedDB/Web Crypto安全容器)获取。
- 生产环境必须启用HTTPS,避免加密数据和密钥在传输过程中被拦截。
- 后端CORS配置建议限制具体域名(而非
origin:'*'),降低跨域风险。
内容的提问来源于stack exchange,提问作者alex1409
相关产品推荐
相关产品推荐

