Node.js Express路由中如何正确挂载使用自定义分页中间件
代码问题与修改方案
你的代码跑不通是四个核心问题导致的:
- 分页中间件默认针对内存静态数组做切片,但你实际用的是Mongoose模型做MongoDB异步查询,中间件执行时拿不到实际数据集,切片逻辑完全不生效
- 控制器里直接返回全量查询结果,根本没有读取中间件挂载在
res.paginatedResults上的分页数据 - 分页参数没有兜底默认值,请求不带
page/limit时会得到NaN,索引计算直接报错 - 原路由文件漏了
router挂载到app的逻辑,路由本身就不会生效
1. 重写分页中间件
适配Mongoose异步查询逻辑,加参数兜底,直接在中间件完成分页查询和结果组装:
const paginatedResults = (model) => { return async (req, res, next) => { // 分页参数兜底:默认第1页,每页10条,非法负数参数强制转1 const page = Math.max(parseInt(req.query.page) || 1, 1); const limit = Math.max(parseInt(req.query.limit) || 10, 1); const skipCount = (page - 1) * limit; try { // 先查数据总条数,用于计算前后页 const total = await model.countDocuments(); const paginatedData = {}; // 组装后页信息 if (skipCount + limit < total) { paginatedData.next = { page: page + 1, limit: limit } } // 组装前页信息 if (skipCount > 0) { paginatedData.previous = { page: page - 1, limit: limit } } // 执行分页查询 paginatedData.results = await model.find().skip(skipCount).limit(limit); paginatedData.total = total; paginatedData.currentPage = page; paginatedData.pageSize = limit; res.paginatedResults = paginatedData; next(); } catch (err) { next(err); } }; }; module.exports = { paginatedResults };
2. 修改控制器逻辑
控制器不再直接查全表,直接返回中间件组装好的分页结果即可:
exports.findAll = (req, res) => { res.send(res.paginatedResults); };
3. 修正路由挂载逻辑
补全路由挂载、依赖引入代码,完全符合你期望的中间件挂载写法:
const projects = require('../controllers/project.controller'); const pagination = require('../替换为你的分页中间件实际路径'); // 引入你的Mongoose Project模型 const Project = require('../替换为你的Project模型实际路径'); module.exports = (app) => { const router = require('express').Router(); // 按你想要的方式挂载分页中间件 router.get('/', pagination.paginatedResults(Project), projects.findAll); // 补全原代码漏掉的路由挂载步骤,路由前缀可以根据你的业务调整 app.use('/api/projects', router); };
如果后续需要加筛选、排序逻辑,只需要在路由层加前置中间件把筛选条件、排序规则挂到
req上,在分页中间件里读取对应参数传入countDocuments和find方法即可,不需要改动核心分页逻辑。
内容的提问来源于stack exchange,提问作者FriedrichGLX
相关产品推荐
相关产品推荐

