Node-Express项目中Mongoose.Model.findByID无法获取单条数据问题求助
问题产生原因
- 核心问题为路由路径重复拼接:你在入口文件index.js中已经给notes路由模块统一挂载了
/notes前缀,而路由配置文件内的单条查询路由又额外定义了/notes/:noteId路径,两者拼接后实际生效的接口路径为/notes/notes/[noteId],你请求的/notes/[noteId]没有匹配到任何注册路由,因此Express直接返回404 Cannot GET错误。 - 存在两个潜在异常点:一是代码中直接使用
ObjectId()构造方法,若未提前从mongoose中导入该方法,即使路由修正后也会抛出未定义错误;二是async/await与.then链式调用混写,写法不规范易引发逻辑异常。
解决方案
- 修正路由配置
删除路由文件中单条查询路径的多余/notes前缀,同时可省略无意义的包裹箭头函数,修改后代码如下:
// 原代码:router.get('/notes/:noteId', (...args) => notes.findOne(...args)); router.get('/:noteId', notes.findOne);
修改后接口路径和你请求的/notes/[noteId]即可匹配。
- 简化查询逻辑,规避ObjectId导入问题
Mongoose提供的findById方法原生支持直接传入字符串格式的ObjectId,无需手动转换,可直接修改查询代码,同时将混写的异步逻辑统一为async/await + try/catch写法,可读性更高:
// 若仍需使用ObjectId可加上这行导入,不需要的话可以省略 const { ObjectId } = require('mongoose').Types; exports.findOne = async (req, res) => { try { const note = await Note.findById(req.params.noteId) if(!note) { return res.status(404).send({ message: "Note not found with id " + req.params.noteId }); } res.send(note); } catch(err) { console.log(err) if(err.kind === 'ObjectId') { return res.status(404).send({ message: "Note not found with id " + req.params.noteId }); } return res.status(500).send({ message: "Error retrieving note with id " + req.params.noteId }); } }
修改完成后重启服务即可正常请求接口获取数据。
内容的提问来源于stack exchange,提问作者Thiluxan
相关产品推荐
相关产品推荐

