React经Node.js向MongoDB传数据报错connectDB.collection不是函数
报错根因
TypeError: connectDB.collection is not a function由4个叠加问题导致:
connectDB是async异步函数,直接调用拿到的是pending状态的Promise对象,不是实际的数据库连接实例,自然不存在collection方法- 你用Mongoose做连接,却调用了原生MongoDB驱动的
collection()语法,Mongoose返回的连接实例根对象本身不挂载这个方法 - Express服务没有配置JSON请求体解析中间件,哪怕数据库连通,也读不到前端POST传过来的
req.body内容 - 前端fetch请求直接传JS对象作为body,没有做JSON序列化,实际发出去的请求格式不对
修复方案
1. 修正前端React提交逻辑
fetch不会自动把JS对象转成JSON格式传输,必须手动序列化:
handleSubmit = () => { console.log("its running"); const databody = { message: this.state.val, }; console.log(" the message is :" + this.state.val); return fetch("http://localhost:5000/stored", { method: "POST", body: JSON.stringify(databody), // 手动转JSON字符串 headers: { "Content-Type": "application/json", }, }) .then((res) => res.json()) .then((data) => console.log(data)); };
2. 修正Node服务入口index.js
必须等数据库连接成功后再启动服务、挂载业务路由,同时提前配置好请求体解析中间件:
const express = require("express"); const cors = require("cors"); const dotenv = require("dotenv"); const port = 5000; const connectDB = require("./config/db"); dotenv.config({ path: "./config/config.env" }); const app = express(); // 注册JSON解析中间件,必须在路由定义前注册 app.use(express.json()); app.use(cors({ origin: "*" })); app.get("/", (req, res) => { res.send("Hey there!"); }); app.get("/Pinged", function (req, res) { res.send("Pinged!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); }); // 等数据库连接完成再启动服务 connectDB().then(() => { // 引入数据模型 const Message = require("./models/Message"); app.post("/stored", async (req, res) => { console.log("received data: ", req.body); try { const savedRecord = await Message.create(req.body); res.json({ msg: "save success", data: savedRecord }); } catch (err) { console.error(err); res.status(500).json({ msg: "save failed" }); } }); app.listen(port, () => console.log(`Example app listening on port ${port}!`)); });
3. 新增Mongoose数据模型文件
Mongoose是ODM工具,必须先定义Schema和集合结构才能操作数据,新建models/Message.js:
const mongoose = require("mongoose"); const messageSchema = new mongoose.Schema({ message: { type: String, required: true } }, { timestamps: true }); // 第一个参数是模型名,第二个是Schema,Mongoose会自动对应到复数形式的messages集合 module.exports = mongoose.model("Message", messageSchema);
如果你坚持要用原生MongoDB的
collection()写法操作数据,不需要Mongoose模型,可以在db.js连接成功后拿到原生db实例:const db = conn.connection.db,后续调用db.collection("你的集合名").insertOne()即可,但不推荐混用Mongoose和原生驱动语法,容易出现不可预期的兼容问题。
内容的提问来源于stack exchange,提问作者william
相关产品推荐
相关产品推荐

