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

Express.js代理POST请求超时失效,GET请求可正常工作

Express.js代理POST请求超时失效,GET请求可正常工作

嘿,看起来你在Express代理中遇到了POST请求超时的问题,但GET请求却能正常运行对吧?咱们先看看你提供的代码,找出几个可能的问题点,再一步步解决:

你的原始代码

require('dotenv').config();

const express = require("express");
const httpProxy = require('http-proxy');
const proxy = httpProxy.createProxyServer({});
const PORT = process.env.PORT || 3001;

const app = express();

app.use(express.json());  // Ensure JSON request bodies are parsed

// Log all incoming requests
app.use((req, res, next) => {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    next();
});

app.get("/api", (req, res) => {
    res.json({ message: "Hello from server!" });
    console.log('Handled /api request');
});

// Middleware for proxying to motchi process
app.use((req, res, next) => {
    if (req.url.startsWith('/get-user-data/')) {
        console.log(`Proxying GET request to motchi process: ${req.url}`);
        proxy.web(req, res, { target: 'http://localhost:5000' }, (error) => {
            if (error) {
                console.error('Proxy error:', error);
                // 这里没有给客户端返回响应,会导致客户端一直等待超时
            }
        });
    } else {
        next();
    }
});

问题分析

  1. 错误处理不完整:当代理发生错误时,你只打印了错误日志,但没有给客户端返回任何响应,这会导致客户端一直等待直到超时。
  2. POST请求的body传递问题:你用了express.json()解析POST的JSON body,但代理时没有把解析后的body重新写入到代理请求中,目标服务器可能无法获取到POST数据,导致请求挂起。
  3. 缺少超时设置:没有给代理请求设置超时时间,一旦目标服务器无响应,代理会一直等待。

修复后的代码

require('dotenv').config();

const express = require("express");
const httpProxy = require('http-proxy');
const proxy = httpProxy.createProxyServer({});
const PORT = process.env.PORT || 3001;

const app = express();

// 解析JSON请求体,后续代理时会重新写入
app.use(express.json());

// 日志中间件
app.use((req, res, next) => {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    next();
});

// 测试接口
app.get("/api", (req, res) => {
    res.json({ message: "Hello from server!" });
    console.log('Handled /api request');
});

// 代理所有以/get-user-data/开头的请求(支持GET/POST等所有方法)
app.use('/get-user-data/', (req, res) => {
    console.log(`Proxying ${req.method} request to motchi process: ${req.url}`);
    
    // 设置代理超时时间,比如5秒
    proxy.setTimeout(5000);
    
    proxy.web(req, res, { target: 'http://localhost:5000' }, (error) => {
        console.error('Proxy error:', error);
        // 给客户端返回明确的错误响应,避免超时
        if (!res.headersSent) {
            res.status(500).json({ 
                error: "代理请求失败", 
                details: error.message 
            });
        }
    });
});

// 全局监听代理错误,兜底处理
proxy.on('error', (err, req, res) => {
    console.error('全局代理错误:', err);
    if (!res.headersSent) {
        res.status(500).json({ error: "代理过程中发生错误" });
    }
});

// 处理POST请求的body传递:把解析后的JSON重新写入代理请求
proxy.on('proxyReq', (proxyReq, req, res, options) => {
    if (req.body && Object.keys(req.body).length > 0) {
        const bodyJson = JSON.stringify(req.body);
        // 更新代理请求的头部
        proxyReq.setHeader('Content-Type', 'application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyJson));
        // 写入body数据
        proxyReq.write(bodyJson);
        proxyReq.end();
    }
});

app.listen(PORT, () => {
    console.log(`服务器运行在端口 ${PORT}`);
});

修改说明

  • 完善错误处理:不管是代理回调的错误还是全局代理错误,都会给客户端返回500错误响应,避免客户端无限等待超时。
  • 支持所有请求方法:将代理中间件改成匹配/get-user-data/路径,自动处理GET、POST等所有HTTP方法。
  • 修复POST body传递:通过proxyReq事件,把express.json()解析后的body重新写入到代理请求中,确保目标服务器能获取到POST数据。
  • 添加超时设置:给代理请求设置5秒超时,超过时间自动终止并返回错误。

备注:内容来源于stack exchange,提问作者Tim M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 07:34:31