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

Express.js服务器POST请求/collect-info出现404错误求助

Express.js POST请求404 Not Found问题解决

问题描述

开发基于Express.js的Web应用时,点击表单提交按钮向服务器/collect-info路径发送POST请求,浏览器控制台出现“404 Not Found”错误,请求地址为http://localhost:3000/collect-info。

已执行的排查操作

  • 检查服务器日志,无任何输出
  • 确认服务器正常运行
  • 验证POST请求处理路由逻辑
  • 在fetch请求前添加console.log语句,可正常打印“Submit button clicked.”和“Sending email...”
  • 关闭防火墙,更换Chrome与Firefox浏览器,问题仍未解决

相关代码

HTML表单代码

<form action="/collect-info" method="post">
    <div>
        <label for="fname">First name:</label>
        <br>
        <input type="text" id="fname" placeholder="First name" name="fname" />
    </div>
    <div>
        <label for="lname">Last name:</label>
        <br>
        <input type="text" id="lname" placeholder="Last name" name="lname">
    </div>
    <div>
        <label for="mail">Email:</label>
        <br>
        <input type="email" id="mail" placeholder="Email" name="user_email" />
    </div>
    <div>
        <label for="country">Country:</label>
        <br>
        <input type="text" id="country" placeholder="Country" name="user_country" />
    </div>
    <div>
        <label for="level">Level:</label>
        <br>
        <input type="range" id="level" name="user_level" min="0" max="5" />
        <span id="level-indicator">Select your Level</span>
    </div>
    <div>
        <label for="msg">Message:</label>
        <br>
        <textarea id="msg" placeholder="Message" name="user_message"></textarea>
    </div>
    <div>
        <label for="submit"></label>
        <br>
        <input type="submit" value="Submit" id="submit-button">
    </div>
</form>

<script src="js/sendEmail.js"></script>
<script src="js/script.js"></script>

前端JS代码

function sendEmail(formData) {
    console.log("Sending email...");
    fetch('/collect-info', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(formData),
    })
    .then(response => response.text())
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error('Error:', error);
    });
}

document.addEventListener("DOMContentLoaded", function () {
    const submitButton = document.getElementById("submit-button");

    submitButton.addEventListener("click", function (event) {
        event.preventDefault();
        console.log("Submit button clicked.");

        const formData = {
            fname: document.getElementById("fname").value,
            lname: document.getElementById("lname").value,
            user_email: document.getElementById("mail").value,
            user_country: document.getElementById("country").value,
            user_level: document.getElementById("level").value,
            user_message: document.getElementById("msg").value
        };

        sendEmail(formData);
    });
});

后端Express代码

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const nodemailer = require('nodemailer');
const path = require('path');  
const bodyParser = require('body-parser');

app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: true })); 

app.use((req, res) => {
    res.status(404);
    res.send('<h1>Error 404: Resource not found</h1>')
})

app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

app.post('/collect-info', (req, res) => {
    console.log('POST request received');
    const formData = req.body;

    const transporter = nodemailer.createTransport({
        service: 'gmail',
        auth: {
            user: '******@gmail.com', 
            pass: '***********', 
        },
    });

    const mailOptions = {
        from: '*******@gmail.com', 
        to: '*****@******', 
        subject: 'New Form Submission',
        text: `Name: ${formData.fname} ${formData.lname}\nEmail: ${formData.user_email}\nMessage: ${formData.user_message}`,
    };

    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            console.error('Error sending email:', error);
            res.status(500).send('Error sending email');
        } else {
            console.log('Email sent:', info.response);
            res.send('Form submitted successfully!');
        }
    });
});

问题分析

  1. 路由匹配顺序错误:Express按代码顺序匹配路由,你的后端代码中404兜底中间件放在了/collect-info POST路由之前,导致所有请求先被这个中间件拦截,后续业务路由永远不会执行,这是404错误的核心原因。
  2. JSON请求体解析缺失:前端通过fetch发送JSON格式请求体,但后端仅配置了bodyParser.urlencoded,缺少JSON解析中间件,即使路由修复后,后端也无法正确读取req.body数据。

解决方案

1. 调整路由顺序

将404兜底中间件移到所有业务路由之后,确保先匹配具体路由:

// 先定义业务路由
app.post('/collect-info', (req, res) => {
    // 路由逻辑...
});

// 最后定义404兜底中间件
app.use((req, res) => {
    res.status(404);
    res.send('<h1>Error 404: Resource not found</h1>')
});

2. 添加JSON解析中间件

在bodyParser.urlencoded之后添加JSON解析支持:

app.use(bodyParser.urlencoded({ extended: true }));
// 添加JSON解析中间件
app.use(bodyParser.json());
// Express 4.16+也可使用自带解析
// app.use(express.json());

修正后的完整后端代码

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const nodemailer = require('nodemailer');
const path = require('path');  
const bodyParser = require('body-parser');

app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: true })); 
app.use(bodyParser.json());

// 定义POST路由
app.post('/collect-info', (req, res) => {
    console.log('POST request received');
    const formData = req.body;

    const transporter = nodemailer.createTransport({
        service: 'gmail',
        auth: {
            user: '******@gmail.com', 
            pass: '***********', 
        },
    });

    const mailOptions = {
        from: '*******@gmail.com', 
        to: '*****@******', 
        subject: 'New Form Submission',
        text: `Name: ${formData.fname} ${formData.lname}\nEmail: ${formData.user_email}\nMessage: ${formData.user_message}\nCountry: ${formData.user_country}\nLevel: ${formData.user_level}`,
    };

    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            console.error('Error sending email:', error);
            res.status(500).send('Error sending email');
        } else {
            console.log('Email sent:', info.response);
            res.send('Form submitted successfully!');
        }
    });
});

// 404兜底中间件放在最后
app.use((req, res) => {
    res.status(404);
    res.send('<h1>Error 404: Resource not found</h1>')
});

app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:51:30