React应用调用MySQL连接方法报Net.createConnection不是函数错误求助
错误原因
- 你使用的
mysql是Node.js服务端专属依赖包,只能在Node运行时环境下执行,它依赖Node内置的net、stream等系统级API。而React代码最终运行在用户浏览器的沙箱环境中,浏览器JS引擎没有提供这类原生API,自然会抛出Net.createConnection is not a function的报错。 - 单独运行dbUtils文件时你是通过Node命令执行,有完整的Node运行环境支持,所以能正常执行;一旦放到前端React组件里调用,运行环境切换为浏览器就会触发错误。
- 额外安全提示:绝对不能把数据库连接逻辑直接写在前端代码中,你的数据库host、账号、明文密码会直接打包到前端静态资源里,任何人都可以通过页面源码拿到这些凭证直接操作你的数据库,存在极高的被拖库、删表的风险。
解决方案
你需要补充一层后端服务层,前后端分离实现功能,核心逻辑如下:
- 把所有数据库操作逻辑全部放到后端服务中执行,使用Node.js的Express、Koa等框架搭建简单的后端服务,dbUtils仅在后端代码中引入调用。
- 前端React代码移除所有对
mysql依赖的引用,删除直接操作数据库的逻辑,改成调用后端提供的HTTP接口完成登录、注册等业务。 - 后端收到前端的请求后,再调用dbUtils中的方法操作数据库,处理完成后将结果返回给前端即可。
- 额外优化建议:密码传输和存储都要做加密处理,禁止明文传输、明文存储用户密码。
简易代码示例
后端Node服务示例(用Express实现)
// 后端服务入口文件app.js,仅在Node环境运行 const express = require('express'); const cors = require('cors'); const mysql = require('mysql'); const app = express(); let connection; // 初始化数据库连接 function initCon(){ connection = mysql.createConnection({ host : '你的数据库地址', user : '你的数据库账号', password : '你的数据库密码' }); connection.connect(); } // 跨域和请求体解析中间件 app.use(cors()); app.use(express.json()); // 注册接口 app.post('/api/signup', (req, res) => { const { dispName, email, pw } = req.body; // 此处可补充参数合法性校验逻辑 connection.query("INSERT INTO typeTestdb.user_table (display_name,user_email,password) VALUES (?,?,?);",[dispName, email, pw], function (error, results) { if (error) { return res.status(400).json({msg: "邮箱已注册,请直接登录"}); } res.json({msg: "账号创建成功"}); }); }) // 启动服务时初始化数据库连接 app.listen(3001, () => { initCon(); console.log('后端服务启动在3001端口'); })
前端SignIn组件修改示例
// 移除对dbUtils的引入 const SignInModal = ({ showSignIn, setShowSignIn }) => { const modalRef = useRef(); const [showSignUp, setShowSignUp] = useState(false); // 提交表单改成调用后端接口 async function submitForm() { if (showSignUp) { try { const response = await fetch('http://localhost:3001/api/signup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ dispName: values.username, email: values.email, pw: values.password }) }); const result = await response.json(); console.log(result.msg); } catch (err) { console.error('请求失败', err); } } setShowSignIn(false); values.email = ''; values.username = ''; values.password = ''; values.password2 = ''; } useEffect( () => { document.addEventListener('keydown', keyPress); // 移除前端初始化数据库连接的逻辑 return () => document.removeEventListener('keydown', keyPress); }, [keyPress] ); return ( <> <div>lots of html</div> </> ); } export default SignInModal
内容的提问来源于stack exchange,提问作者Colin Harker
相关产品推荐
相关产品推荐

