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

Node.js博客开发问题:对象被重复推入posts数组

Express博客中文章重复添加到数组的问题解决

问题描述

开发博客网站时,在app.post("/compose", function() {})路由中将用户提交的数据推入全局posts数组后,每次提交一条内容,数组中会出现两条相同条目,而非预期的一条。

可能原因

  1. 浏览器重复发送POST请求:比如用户双击提交按钮、表单被JS重复触发提交,或者浏览器因响应异常自动重试请求。
  2. 前端表单存在重复提交逻辑:例如表单同时设置了默认提交行为和JS绑定的submit事件,导致请求被发送两次。
  3. 代码小疏漏:原代码中contact路由的contactPageContent错误使用了aboutContent,虽不直接导致重复提交,但属于逻辑错误。

解决方案

方案1:前端阻止重复提交

在提交表单后立即禁用提交按钮,防止用户双击或重复触发:

<!-- compose页面的表单 -->
<form action="/compose" method="POST">
  <input type="text" name="postTitle" required>
  <textarea name="blogContent" required></textarea>
  <button type="submit" id="submitBtn">发布文章</button>
</form>

<script>
const submitBtn = document.getElementById('submitBtn');
document.querySelector('form').addEventListener('submit', function() {
  submitBtn.disabled = true; // 提交后禁用按钮,避免重复触发
});
</script>

方案2:后端添加防重复逻辑

给每个文章添加唯一ID,在推入数组前检查是否已有相同ID的条目,同时显式返回响应确保函数终止:

app.post('/compose', function (req, res) {
    let post = {
        newTitle: req.body.postTitle,
        newContent: req.body.blogContent,
        id: Date.now() // 用时间戳生成唯一标识
    };

    // 过滤重复请求
    if (!posts.some(item => item.id === post.id)) {
        posts.push(post);
    }

    return res.redirect('/'); // 显式return,确保响应发送后终止函数执行
});

方案3:检查路由重复注册

确认代码中没有重复定义app.post("/compose")路由,避免同一请求被多次处理。

修正后的完整后端代码

//jshint esversion:6
const express = require('express');
const bodyParser = require('body-parser');
const ejs = require('ejs');

const homeStartingContent = 'Lacus vel facilisis ...';
const aboutContent = 'Hac habitasse platea dictumst ...';
const contactContent = 'Scelerisque eleifend donec pretium...';

const app = express();

app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));

let posts = [];

app.get('/', function (req, res) {
    res.render('home', {
        homePageContent: homeStartingContent,
        listContent: posts,
    });
});

app.get('/about', function (req, res) {
    res.render('about', { aboutPageContent: aboutContent });
});

app.get('/contact', function (req, res) {
    res.render('contact', { contactPageContent: contactContent }); // 修正原代码的内容错误
});

app.get('/compose', function (req, res) {
    res.render('compose');
});

app.post('/compose', function (req, res) {
    let post = {
        newTitle: req.body.postTitle,
        newContent: req.body.blogContent,
        id: Date.now()
    };

    if (!posts.some(item => item.id === post.id)) {
        posts.push(post);
    }

    return res.redirect('/');
});

app.listen(3000, function () {
    console.log('Server started on port 3000');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 12:07:41