Node+MongoDB项目特定路由无响应,请求持续加载
问题描述
我正在开发一个练习用小型API,从MongoDB集合获取数据时遇到问题:访问特定路由(比如/authors)时,控制器无任何返回,API一直处于加载状态,没有响应。项目启动时数据库连接正常,控制台会输出连接成功提示,但请求/authors这类路由时既无结果也无报错,请求无限加载。之前做过类似的学习API运行正常,不知道当前问题出在哪。环境变量MONGODB_URI已配置集合名称。
代码文件
server.js
const express = require('express'); const mongodb = require('./db/connect'); const app = express(); const bodyParser = require('body-parser'); const port = process.env.PORT || 3000; app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use('/', require('./routes')); process.on('uncaughtException', (err, origin) => { console.log( process.stderr.fd, `Caught exception: ${err}\n` + `Exception origin: ${origin}` ); }); mongodb.initDb((err) => { if (err) { console.log('数据库连接失败'); } else { app.listen(port); console.log(`已连接数据库并监听端口 ${port}`); } });
db/connect.js
const dotenv = require('dotenv'); dotenv.config(); const MongoClient = require('mongodb').MongoClient; let _db; const initDb = (callback) => { if (_db) { console.log('数据库已初始化!'); return callback(null, _db); } MongoClient.connect(process.env.MONGODB_URI) .then((client) => { _db = client; callback(null, _db); }) .catch((err) => { callback(err); }); }; const getDb = () => { if (!_db) { throw Error('数据库未初始化'); } return _db; }; module.exports = { initDb, getDb, };
routes/index.js
const express = require('express'); const router = express.Router(); router.get('/', (req, res) => { res.send('运行中'); }); router.use('/authors', require('./authors')); module.exports = router;
routes/authors.js
const express = require('express'); const router = express.Router(); const authorsController = require('../controllers/authorsController'); router.get('/', authorsController.getAll); /*router.get('/:id', authorsController.getAuthorById); router.get('/:id/books', authorsController.getAuthorBooks); router.post('/', authorsController.addNewAuthor); router.put('/:id', authorsController.updateAuthorInfo); router.delete('/:id', authorsController.deleteAuthor);*/ module.exports = router;
controllers/authorsController.js
const mongodb = require('../db/connect'); const ObjectId = require('mongodb').ObjectId; const getAll = async (req, res) => { const result = await mongodb.getDb().db().collection('authors').find(); result.toArray((err, lists) => { if (err) { res.status(400).json({ message: err }); } res.setHeader('Content-Type', 'application/json'); res.status(200).json(lists); }); }; const getAuthorById = async (req, res) => { if (!ObjectId.isValid(req.params.id)) { res.status(400).json('Author ID格式无效'); } const userId = req.params.id; const result = await mongodb .getDb() .db() .collection('authors') .find({ _id: userId }); result.toArray((err, lists) => { if (condition) { res.status(400).json({ message: err }); } res.setHeader('Content-Type', 'application/json'); res.status(200).json(lists); }); }; module.exports = { getAll, getAuthorById, };
package.json 依赖
{ "body-parser": "^1.20.3", "dotenv": "^16.4.5", "express": "^4.21.1", "mongodb": "^6.9.0", "nodemon": "^3.1.7" }
问题根源与修复方案
1. 异步模式混用导致响应阻塞
控制器中同时使用async/await和回调函数处理MongoDB游标,且未正确终止错误分支的响应流程,导致Express无法结束请求。
修复后的getAll方法:
const getAll = async (req, res) => { try { const collection = mongodb.getDb().db().collection('authors'); const lists = await collection.find().toArray(); res.setHeader('Content-Type', 'application/json'); res.status(200).json(lists); } catch (err) { res.status(500).json({ message: err.message }); } };
2. getAuthorById中的语法错误与类型不匹配
- 代码中
if (condition)的condition未定义,会触发未捕获异常 - 查询
_id时使用字符串而非ObjectId类型,MongoDB无法匹配文档
修复后的getAuthorById方法:
const getAuthorById = async (req, res) => { if (!ObjectId.isValid(req.params.id)) { return res.status(400).json('Author ID格式无效'); } try { const userId = new ObjectId(req.params.id); const collection = mongodb.getDb().db().collection('authors'); const author = await collection.find({ _id: userId }).toArray(); res.setHeader('Content-Type', 'application/json'); res.status(200).json(author); } catch (err) { res.status(500).json({ message: err.message }); } };
3. 全局错误处理缺失
添加Express错误处理中间件,捕获未处理的异常并返回响应:
在server.js的所有路由之后添加:
app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ message: '服务器内部错误' }); });
4. 数据库实例验证
确保MONGODB_URI包含目标数据库名称(例如mongodb://localhost:27017/bookstore),若未指定,需在db().db('your-db-name')中明确传入数据库名。
内容的提问来源于stack exchange,提问作者Jesus Contreras
相关产品推荐
相关产品推荐

