MongoDB先返回对象后返回null致Node.js应用崩溃求助
问题
我正在开发一个存储文章的简易博客网站,使用MongoDB数据库,仅存储title和content两个属性。问题在于,当我通过自定义路由参数(参数为文章title)访问时,能够找到对象并渲染页面,但随后应用崩溃,无法继续网站导航。
相关路由代码:
app.get("/:day", async function(req,res){ let customPost = await blogPost.findOne({title : req.params.day}) console.log(customPost) res.render("postTemplate", {dayNumber : customPost.title, postText : customPost.content}) })
控制台输出:
{ _id: new ObjectId("645af28168fe4384c8792cd1"), title: 'efawefawe', content: 'fseaweawelj', __v: 0 } null D:\Microsoft VS Code\Web Development Projects\Blog Website\index.js:57 res.render("postTemplate", {dayNumber : customPost.title, postText : customPost.content}) ^ TypeError: Cannot read properties of null (reading 'title') at D:\Microsoft VS Code\Web Development Projects\Blog Website\index.js:57:56 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) Node.js v19.8.1 [nodemon] app crashed - waiting for file changes before starting...
我无法理解为何先找到对象并输出,随后输出null,进而因无法读取customPost属性导致崩溃。EJS模板几秒后能正常渲染文章,但之后无法访问网站其他页面。
解决方案
核心原因
/:day是全局匹配路由,会拦截所有未被其他路由定义的请求,包括页面加载时的静态资源(CSS、JS、图片等)、其他页面路由。- 第一次请求匹配到对应标题的文章,控制台输出找到的文档;但浏览器紧接着加载静态资源时,
req.params.day变成了静态资源文件名(比如style.css),数据库中没有该标题的文章,findOne返回null,直接访问null.title触发报错,导致应用崩溃。
修复措施
- 调整路由顺序:将具体路由(如首页
/、关于页/about)放在/:day路由之前,确保特定路由优先匹配,不会被全局路由拦截。 - 增加空值判断:在渲染页面之前检查查询结果是否存在,避免访问null的属性:
app.get("/:day", async function(req,res){ let customPost = await blogPost.findOne({title : req.params.day}) if (!customPost) { // 返回404页面或提示信息 return res.status(404).render("404", {message: "该文章不存在"}) } console.log(customPost) res.render("postTemplate", {dayNumber : customPost.title, postText : customPost.content}) })
- 隔离静态资源:确保静态资源通过专门的路由处理,比如使用
app.use(express.static('public')),并将静态资源放在public目录下,访问路径为/public/xxx,避免被/:day路由捕获。
内容的提问来源于stack exchange,提问作者Louis_F
相关产品推荐
相关产品推荐

