解决方案参考: https://github.com/chimurai/http-proxy-middleware/issues/40

nodejs 服务器在之前使用了 bodyParser 把 body 的数据解析出来,以供处理。

但是后来有些接口需要转发到其他的域名对应的服务器,不想在前端写死,就在 nodejs 服务上引用了 http-proxy-middleware 做代理转发。get 请求的时候没什么问题,但是 post 请求会报 ECONNRESET 错误。后来查了资料和同事讨论知道了原因。英文不错的话可以直接看上面的引用链接。

下面的是之前的代码,是因为使用了 bodyParser 导致的代理转发带有 body 数据的 post 请求会失败。

var proxyMiddleware = require('http-proxy-middleware');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

var apiProxy = proxyMiddleware('/otherApi/**', {
   target: 'https://xxx.xxx.xxx.xxx',
   pathRewrite: { '^/otherApi': '/api' },
   secure: false,
   changeOrigin: true,
});
app.use(apiProxy);

所以我们可以在代理中加上把解析后的 body 数据再转回来即可。

var proxyMiddleware = require('http-proxy-middleware');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

var restream = function(proxyReq, req, res, options) {
   if (req.body) {
       let bodyData = JSON.stringify(req.body);
       // incase if content-type is application/x-www-form-urlencoded -> we need to change to application/json
       proxyReq.setHeader('Content-Type','application/json');
       proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
       // stream the content
       proxyReq.write(bodyData);
  }
}
var apiProxy = proxyMiddleware('/otherApi/**', {
   target: 'https://xxx.xxx.xxx.xxx',
   pathRewrite: { '^/otherApi': '/api' },
   secure: false,
   changeOrigin: true,
   onProxyReq: restream
});
app.use(apiProxy);