使用Mongoose通过ID查询MongoDB文档时出现404错误求助
解决Mongoose查询MongoDB文档时的404错误
我帮你梳理下代码里的几个关键问题,这些大概率是导致你遇到404错误的原因:
1. 未处理「查询无结果」的场景,且模板渲染变量错误
你当前的代码只处理了查询出错的情况,但如果Blog.findOne没匹配到文档(哪怕你确认数据库里有),blog会是null,这时候你没有返回任何响应,服务器会挂起直到超时,前端就会收到404。另外你渲染模板时用了未定义的entry变量,这明显是笔误,应该用查询结果blog。
修正后的代码片段:
router.get('/blogs/:id', function(req, res){ console.log('getting one blog post by id'); Blog.findOne({ _id: req.params.id }) .exec(function (err, blog) { if(err){ // 给错误响应加上500状态码,更规范 return res.status(500).send('Error occurred'); } // 新增:如果没找到文档,明确返回404 if(!blog){ return res.status(404).send('Blog post not found'); } console.log(blog); // 把变量名改成实际的查询结果blog res.render('entry', {entries: blog}); }) });
2. 验证ObjectId格式是否合法
虽然Mongoose会自动尝试把字符串转为ObjectId,但如果req.params.id的格式不符合MongoDB ObjectId规则(比如不是24位十六进制字符),findOne会直接返回null,触发上面的404。你可以先加一层格式校验:
const mongoose = require('mongoose'); router.get('/blogs/:id', function(req, res){ // 先检查ID格式是否有效 if(!mongoose.Types.ObjectId.isValid(req.params.id)){ return res.status(400).send('Invalid blog ID format'); } console.log('getting one blog post by id'); Blog.findOne({ _id: req.params.id }) .exec(function (err, blog) { // 后续处理和上面一致 }) });
3. 确认模板文件存在且路径正确
你调用了res.render('entry', ...),如果views目录下没有对应的entry模板文件(比如文件名拼写错、扩展名不对,比如你用EJS但文件是entry.html),Express会抛出错误,间接导致前端收到404或500。务必检查模板文件的位置和名称是否完全匹配。
4. 检查路由挂载的前缀
如果你的路由是通过带前缀的方式挂载的(比如app.use('/api', router)),那实际访问路径应该是/api/blogs/:id,而不是/blogs/:id。如果前端请求的路径和实际路由不匹配,自然会收到404。
内容的提问来源于stack exchange,提问作者arcticlisa
相关产品推荐
相关产品推荐

