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!'); } }); });
问题分析
- 路由匹配顺序错误:Express按代码顺序匹配路由,你的后端代码中404兜底中间件放在了
/collect-infoPOST路由之前,导致所有请求先被这个中间件拦截,后续业务路由永远不会执行,这是404错误的核心原因。 - 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
相关产品推荐
相关产品推荐

