Express.js POST请求路由未正常处理问题求助
Express.js POST请求404错误排查与解决
核心问题:实现Python脚本接收HTML输入并将输出返回至HTML展示功能时,遇到Express.js的POST请求无法处理,浏览器控制台提示POST http://localhost:3000/runSF 404 (Not Found)。
相关信息
- 文件夹结构:项目根目录包含
routes、views、public文件夹,以及app.js、SFscript.py等核心文件。 - HTML中的jQuery脚本:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function () { $("#submit_SF").click(function () { var userChoice = $("#score_function").val(); $.ajax({ url: "/runSF", method: "POST", data: { choice: userChoice }, success: function (data) { $("#tableData").html(data); } }); }); }); </script>
- app.js文件内容:
var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var bodyParser = require('body-parser'); var { spawn } = require('child_process'); // Define route var var indexRouter = require('./routes/index'); var fsRouter = require('./routes/fs'); var usersRouter = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); // Define route app.use('/', indexRouter); app.use('/fs', fsRouter); app.use('/users', usersRouter); // catch 404 and forward to error handler app.use(function (req, res, next) { next(createError(404)); }); // error handler app.use(function (err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app; app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static('public')); app.post("/runSF", (req, res) => { const userChoice = req.body.choice; console.log("Received POST request with user choice:", userChoice); // Run the Python script with the user's choice as an argument const pythonProcess = spawn('python', ['SFscript.py', userChoice]); pythonProcess.stdout.on('data', (data) => { // Send the Python script's output back to the client const outputData = data.toString(); console.log("Python script output:", outputData); // Log script output res.send(outputData); }); pythonProcess.stderr.on('data', (data) => { console.error("Error executing Python script:", data); // Log script errors }); });
问题根源
- 路由顺序错误:
app.post("/runSF")路由定义放在了404错误处理中间件之后,Express按代码顺序执行中间件/路由,请求会先进入404处理逻辑直接返回404,后续路由根本不会被触发。 - 代码执行时机问题:路由定义写在
module.exports = app;之后,部分启动场景下这部分代码不会被执行,导致路由未注册。 - 重复中间件配置:重复添加了
bodyParser和express.static中间件,可能引发配置冲突。
修复方案
- 调整路由位置:将
app.post("/runSF")移动到404错误处理中间件之前、所有路由use语句之后,示例:
// ... 原有代码 ... // Define route app.use('/', indexRouter); app.use('/fs', fsRouter); app.use('/users', usersRouter); // 新增:runSF路由放在此处 app.post("/runSF", (req, res) => { const userChoice = req.body.choice; console.log("Received POST request with user choice:", userChoice); // 使用绝对路径确保找到Python脚本 const scriptPath = path.join(__dirname, 'SFscript.py'); const pythonProcess = spawn('python', [scriptPath, userChoice]); pythonProcess.stdout.on('data', (data) => { const outputData = data.toString(); console.log("Python script output:", outputData); res.send(outputData); }); pythonProcess.stderr.on('data', (data) => { console.error("Error executing Python script:", data.toString()); // 给客户端返回错误响应,避免请求挂起 res.status(500).send("脚本执行失败:" + data.toString()); }); // 监听脚本退出事件,处理异常退出情况 pythonProcess.on('close', (code) => { console.log("Python脚本退出,状态码:", code); if (code !== 0 && !res.headersSent) { res.status(500).send("脚本异常退出"); } }); }); // catch 404 and forward to error handler app.use(function (req, res, next) { next(createError(404)); }); // ... 后续错误处理代码 ...
删除重复中间件:移除
module.exports = app;之后的app.use(bodyParser.urlencoded...)和app.use(express.static('public')),前面已配置相同内容。校验脚本路径:使用
path.join(__dirname, 'SFscript.py')生成绝对路径,避免spawn找不到脚本文件。完善错误处理:在Python脚本执行出错或异常退出时,给客户端返回明确的错误响应,防止请求长时间挂起。
内容的提问来源于stack exchange,提问作者Saudo Unix
相关产品推荐
相关产品推荐

