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(); } });
问题分析
- 错误处理不完整:当代理发生错误时,你只打印了错误日志,但没有给客户端返回任何响应,这会导致客户端一直等待直到超时。
- POST请求的body传递问题:你用了
express.json()解析POST的JSON body,但代理时没有把解析后的body重新写入到代理请求中,目标服务器可能无法获取到POST数据,导致请求挂起。 - 缺少超时设置:没有给代理请求设置超时时间,一旦目标服务器无响应,代理会一直等待。
修复后的代码
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
相关产品推荐
相关产品推荐

