Express开发博客API遇Route.post需回调却得undefined错误如何解决
问题排查及修复方案
核心报错原因:循环依赖导致auth中间件为undefined
你触发Route.post() requires a callback function but got a [object Undefined]的根本原因是模块循环加载+导出导入逻辑错误:
- 执行顺序问题:
app.js中先执行const article = require('./routes/article')加载路由文件,此时路由文件内部立刻执行const app = require('../app')加载app.js,但此时app.js还没运行到module.exports = {auth}这一行,所以路由拿到的app对象里auth属性为undefined - 额外导出错误:你
app.js仅导出了{auth},并没有导出整个express实例,路由中用app.auth本身也不符合导出规则,就算没有循环依赖也拿不到正确值。
修复循环依赖方案
最优方案是把auth中间件单独抽离到独立文件(比如/middlewares/auth.js),然后在路由和app.js中分别引入,彻底避免循环加载。如果暂时不想抽离,也可以调整导出和加载顺序:
// app.js 调整代码顺序,先定义导出auth,再加载路由 const express = require('express'); const mongoose = require('mongoose'); const env = require('dotenv').config(); const app = express(); // 先定义auth函数,再导出 const auth = (req, res, next) => { // 你原有的auth逻辑 next() } module.exports = {auth, app} // 同时导出auth和app实例 // 导出之后再加载路由 const article = require('./routes/article') app.use(express.json()); app.use(express.urlencoded({extended : true})); // 其余原有代码
然后路由文件中直接引入auth:
// 路由文件中修改引入逻辑 const { auth } = require('../app'); // post路由改为 router.post('/', auth, async (req,res)=>{ // 原有逻辑 })
其他需要修正的错误
- 路由挂载错误:你的路由文件导出的是
module.exports = { router },所以app.js中挂载路由的代码需要改为app.use("/article", article.router) - 未定义变量错误:
- GET路由中你使用了
Post.findOne,但你引入的模型是Article,改为Article.findOne - POST路由中你使用了
User.findOne,但没有引入User模型,需要顶部加const User = require('../models/User') app.js中使用了未定义的port变量,需要加const port = process.env.PORT || 3000
- GET路由中你使用了
- 响应方法调用错误:
res.send(doc).sendStatus(200)写法错误,send执行后就已经结束响应,不能链式调用sendStatus,改为res.status(200).send(doc),catch块的错误响应同理改为res.status(400).send({'error' :you got some error - ${err}}) - Schema默认值错误:Article模型中
date字段的默认值写了Date.now(),会在服务启动时就固定时间,改为default: Date.now(去掉括号),才会在新建文档时动态生成当前时间 - 空值处理漏洞:POST路由中如果
User.findOne没有匹配到用户,doc会是undefined,调用doc._id会报错,需要加空值判断
内容的提问来源于stack exchange,提问作者Shashank Chaudhary
相关产品推荐
相关产品推荐

