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

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
  });
});

问题根源

  1. 路由顺序错误:app.post("/runSF")路由定义放在了404错误处理中间件之后,Express按代码顺序执行中间件/路由,请求会先进入404处理逻辑直接返回404,后续路由根本不会被触发。
  2. 代码执行时机问题:路由定义写在module.exports = app;之后,部分启动场景下这部分代码不会被执行,导致路由未注册。
  3. 重复中间件配置:重复添加了bodyParser和express.static中间件,可能引发配置冲突。

修复方案

  1. 调整路由位置:将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));
});
// ... 后续错误处理代码 ...
  1. 删除重复中间件:移除module.exports = app;之后的app.use(bodyParser.urlencoded...)和app.use(express.static('public')),前面已配置相同内容。

  2. 校验脚本路径:使用path.join(__dirname, 'SFscript.py')生成绝对路径,避免spawn找不到脚本文件。

  3. 完善错误处理:在Python脚本执行出错或异常退出时,给客户端返回明确的错误响应,防止请求长时间挂起。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 00:30:30