Express中/api/events与/api/profile路由指向错误问题排查
解决Express路由混淆问题
问题根源
你遇到的/api/events/和/api/profile/路由混淆的核心原因,是Node.js模块的缓存机制导致你的router.js导出了一个共享的Express Router实例。
当你在events/index.js和profile/index.js里分别require('../../modules/router.js')时,Node.js只会加载一次router.js文件,所以两个模块拿到的是同一个Router对象。这就导致:
- 你在两个模块里分别添加的
get('/')路由,会被注册到同一个Router上; - 当你把这个共享的Router同时挂载到
/api/events和/api/profile路径下时,这个Router里的所有路由会在两个路径下同时生效,自然就出现了路由混淆的情况。
解决方案
把router.js改成工厂函数模式,让它每次被调用时返回一个全新的Router实例,这样每个模块就能拥有独立的Router,互不干扰。
1. 修改router.js文件
将直接导出Router实例改为导出一个创建Router的函数:
const express = require("express") const cookieParser = require('cookie-parser')() const cors = require('cors')({origin: true}) const firebase = require("./firebase.js") // 保持验证中间件逻辑不变 const validateFirebaseIdToken = (req, res, next) => { if ((!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) && !req.cookies.__session) { res.status(403).send({ "error": 'Unauthorized'}) return } let idToken if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) { idToken = req.headers.authorization.split('Bearer ')[1] } else { idToken = req.cookies.__session } firebase.admin.auth().verifyIdToken(idToken).then((decodedIdToken) => { req.user = decodedIdToken return next() }).catch(error => { res.status(403).send({"error": 'Unauthorized'}) }) } // 导出工厂函数,每次调用返回新的Router实例 module.exports = () => { const router = express.Router() router.use(cors) router.use(cookieParser) router.use(validateFirebaseIdToken) return router }
2. 修改events/index.js和profile/index.js
调用工厂函数来创建独立的Router实例:
// events/index.js const createRouter = require('./../../modules/router.js') const router = createRouter() // 创建专属的Router实例 router.get('/', (req, res) => { // 这里写events模块的业务逻辑 }) module.exports = router
// profile/index.js const createRouter = require('./../../modules/router.js') const router = createRouter() // 创建专属的Router实例 router.get('/', (req, res) => { // 这里写profile模块的业务逻辑 }) module.exports = router
为什么这样能解决问题?
修改后,events和profile模块会各自调用createRouter()生成独立的Router实例,它们的路由规则和中间件都是隔离的。当你把它们分别挂载到/api/events和/api/profile路径下时,两个路由就会完全独立工作,不会再出现混淆的情况。
内容的提问来源于stack exchange,提问作者Tometoyou
相关产品推荐
相关产品推荐

