Mongoose连接返回Promise无collection方法的MongoDB操作问题
核心问题说明
你当前代码里const db = connectDB()拿到的是异步函数返回的Promise对象,并非实际的MongoDB连接实例,直接调用db.collection()必然报错。除此之外代码中还有几处会导致功能异常的问题,下面给出完整修正方案。
现存问题汇总
- 环境变量加载顺序错误:
connectDB引入前未加载dotenv配置,db.js内无法读取process.env.MONGO_URI - 重复加载dotenv:先后两次调用
dotenv.config(),属于冗余代码 - 未配置请求体解析中间件:POST请求的
req.body默认是undefined,无法读取前端提交的参数 - 未等待数据库连接完成就启动服务:请求进入时数据库可能还未完成连接,直接操作会报错
collection()调用未传入集合名称:该方法必须指定要操作的集合名,空参调用无法定位到具体存储位置- 引入了未使用的依赖:
request、util两个模块在代码中没有被调用,可以移除 - CORS配置存在安全风险:开发环境可以临时用通配符,生产环境必须替换为实际前端域名
修正后代码
db.js(无需大改,保持原有逻辑即可)
const mongoose = require("mongoose"); const connectDB = async () => { try { const conn = await mongoose.connect(process.env.MONGO_URI, { useUnifiedTopology: true, useNewUrlParser: true, }); console.log(`MongoDB Connected : ${conn.connection.host}`); return conn; } catch (err) { console.error(err.message); process.exit(1); } }; module.exports = connectDB;
index.js(按以下逻辑调整)
// 最先加载环境变量,保证后续所有模块都能读取到配置 require("dotenv").config({ path: "./config/config.env" }); const express = require("express"); const cors = require("cors"); const port = 5000; const connectDB = require("./config/db"); const app = express(); // 注册中间件 app.use(cors({ origin: "*" })); // 生产环境请替换为实际前端域名 // 解析JSON格式请求体 app.use(express.json()); // 解析表单格式请求体 app.use(express.urlencoded({ extended: true })); // 先连接数据库,连接成功后再启动服务 let db; async function startServer() { const conn = await connectDB(); // 拿到原生collection操作实例,替换'my_collection'为你实际要使用的集合名称 db = conn.connection.collection('my_collection'); app.listen(port, () => console.log(`Example app listening on port ${port}!`)); } startServer(); app.get("/", (req, res) => { res.send("Hey there!"); }); app.get("/Pinged", function (req, res) { res.send("Pinged!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); }); app.post("/stored", async (req, res) => { try { console.log("收到提交数据: ", req.body); const data = await db.insertOne(req.body); res.send("saved to db, new record id: " + data.insertedId); } catch (err) { console.log(err); res.status(500).send("数据写入失败"); } });
注意事项
- 代码中
collection('my_collection')的my_collection必须替换为你业务中实际要用的集合名,比如存储表单提交可以叫form_submits - 如果后续用Mongoose的Schema模型做数据校验,可以不用直接操作原生collection,定义对应Model后调用
Model.create()写入数据更规范 - 生产环境务必修改CORS origin配置,不要允许所有来源跨域访问接口
内容的提问来源于stack exchange,提问作者william
相关产品推荐
相关产品推荐

