You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中PUT请求无法覆盖MongoDB内容的问题排查

PUT请求无法更新MongoDB数据的排查与解决

问题描述

跟随教程开发时,使用Express+Mongoose编写PUT接口尝试覆盖MongoDB中的文档,Postman测试无报错,但数据库内容未更新。相关代码及数据库文档格式如下:

原代码

const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");

const app = express();

app.set('view engine', 'ejs');

app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(express.static("public"));

mongoose.connect("mongodb://localhost:27017/wikiDB", {useNewUrlParser: true});

const articleSchema = {
    title: String,
    content: String
};

const Article = mongoose.model("Article", articleSchema);

// Requests Targeting All Routes

app.route("/articles")

.get(function(req, res) {
    Article.find()
        .then((foundArticles) => {
            mongoose.connection.close();
            foundArticles.forEach(function(foundArticle) {
                // console.log(foundArticle);
                res.send(foundArticles);
            })
        })
        .catch(function(err) {
            console.log(err);
        })
})

.post(function(req, res) {
    const newArticle = new Article({
        title: req.body.title,
        content: req.body.content
    });

    newArticle.save()
        .then(function() {
            res.send("Successfully added a new article.");
        })
        .catch(function(err) {
            console.log(err);
        })
})

.delete(function(req, res) {
    Article.deleteMany()
        .then(() => {
            res.send("Successfully deleted the document.");
        })
        .catch(function(err) {
            console.log(err);
        })
});

// Requests Targeting Specific Routes

app.route("/articles/:articleTitle")
.get(function(req, res) {
    const title = req.params.articleTitle;
    Article.find({title})
        .then((foundArticle)  => {
            res.send(foundArticle);
        })
        .catch(function(err) {
            console.log(err);
        })
})

// It won't allow the contents of the database to be overwritten.
.put(function(req, res) {
    Article.replaceOne({ title: req.params.articleTitle },
        {
          title: req.body.title,
          content: req.body.content,
        })
        .then(() => {
            res.send("Successfully updated article.");
        })
        .catch(function(err) {
            console.log(err);
        })
})
app.listen(3000, function() {
    console.log("Server started on port 3000!");
});

数据库文档格式

{
    "_id" : ObjectId("6517a22854d8425f4e613d9e"),
    "title" : "REST",
    "content" : "REST is short for REpresentational State Transfer. It's an architectural style for designing APIs."
}

问题排查与修复

1. 数据库连接被提前关闭

原GET请求中调用了mongoose.connection.close(),这会直接关闭数据库连接池,导致后续所有请求(包括PUT)无法操作数据库。Mongoose会自动维护连接池,无需手动关闭连接(除非应用程序终止)。

修复后的GET请求代码:

.get(function(req, res) {
    Article.find()
        .then((foundArticles) => {
            // 移除mongoose.connection.close();
            res.send(foundArticles); // 直接返回查询结果,无需forEach遍历
        })
        .catch(function(err) {
            res.status(500).send(err); // 将错误返回给客户端,便于排查
        })
})

2. PUT请求未验证更新结果

replaceOne方法在未找到匹配文档时不会抛出错误,仅会返回modifiedCount: 0,原代码直接返回成功信息,无法判断是否真的更新了数据。同时需确保查询条件与数据库文档完全匹配(MongoDB查询默认区分大小写)。

修复后的PUT请求代码:

.put(function(req, res) {
    Article.replaceOne(
        { title: req.params.articleTitle },
        { title: req.body.title, content: req.body.content },
        { runValidators: true } // 可选:确保更新内容符合Schema验证规则
    )
    .then((result) => {
        if (result.modifiedCount === 0) {
            return res.send("未找到匹配的文章,未执行更新操作");
        }
        res.send("文章更新成功");
    })
    .catch(function(err) {
        res.status(500).send(err);
    })
})

3. Postman请求格式验证

发送PUT请求时,需选择x-www-form-urlencoded格式(与bodyParser.urlencoded对应),并正确填写title和content的键值对,否则req.body无法获取到更新数据。

可选优化:使用findOneAndReplace

若需要获取更新后的文档,可改用findOneAndReplace方法,它会返回修改后的文档(需设置new: true):

.put(function(req, res) {
    Article.findOneAndReplace(
        { title: req.params.articleTitle },
        { title: req.body.title, content: req.body.content },
        { new: true, runValidators: true }
    )
    .then((updatedArticle) => {
        if (!updatedArticle) {
            return res.send("未找到匹配的文章");
        }
        res.send(`文章更新成功:${JSON.stringify(updatedArticle)}`);
    })
    .catch(function(err) {
        res.status(500).send(err);
    })
})

内容的提问来源于stack exchange,提问作者Stac Flo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 23:57:11