使用MongoDB+Express做用户认证时报TypeError: Cannot read property '0' of undefined
问题根因
- MongoDB Node.js驱动v3.0及以上版本中,
insertOne接口的返回结果已经移除了ops字段,你代码中尝试访问results.ops[0]时,results.ops为undefined,直接触发Cannot read property '0' of undefined报错。 - 错误被catch捕获后仅打印了日志,没有给前端返回任何响应,导致请求一直挂起,表现为页面无限加载无跳转。
- 存在变量重复声明问题:外层已经声明了
let client,try代码块内部又重新声明了局部client变量,导致外层的client始终为undefined,执行client.close()时会抛出额外的未定义错误。
修复方案
你可以直接替换signUp路由的逻辑为以下内容:
authRouter.route('/signUp').post((req, res) => { const {username, password} = req.body; const url = 'mongodb+srv://Yoshi:Yumcmaster1@cluster0.atic5.mongodb.net?retryWrites=true&w=majority' const dbName = 'testdb'; (async function addUser(){ let client try { // 移除内部的let声明,直接给外层client赋值 client = await MongoClient.connect(url); const db = client.db(dbName); const user = {username, password}; const results = await db.collection('users').insertOne(user); debug(results); // 直接传入构造好的user对象,不需要从results里取 req.login(user, ()=> { res.redirect('/auth/profile'); }); } catch (error) { debug(error) // 捕获错误后返回响应,避免请求挂起 res.status(500).send('注册操作失败,请稍后重试'); } // 安全关闭连接 if (client) { client.close(); } }()); });
如果你需要拿到数据库写入后带自动生成_id的完整用户数据,可以插入后再查询一次:
// 替换掉原来的req.login逻辑 const newUser = await db.collection('users').findOne({ _id: results.insertedId }); req.login(newUser, ()=> { res.redirect('/auth/profile'); });
内容的提问来源于stack exchange,提问作者user14367514
相关产品推荐
相关产品推荐

