前言

前几天遇到了一个没见过的bug,在此记录一下。前几天,新写了一个页面,里面有get请求、json参数的post请求、form参数的post请求,然后把这个项目打包出来的dist放入node中。更新到线上以后,发现仅有json参数的post请求出现nginx 502报错,其他接口都正常。

解决问题的思路

刚开始搜索了一下nginx 502,没发现什么有用信息。

首先是发现其他get接口都正常,点击按钮时这个post接口报错,当时就有点懵。然后检查了同一个项目另一个post接口,发现另一个post接口也正常。所以,推理得json类型参数的post请求有问题。

本地环境,这个json参数的请求没问题,测试环境是用dist+nginx部署的,这个请求也没问题。线上环境是dist+node部署,所以就定位到了http-proxy-middleware这个库。

在node+dist项目中,如果接口就是这个node的就不用代理了,但如果前端代码中请求了别的项目的接口,就需要用http-proxy-middleware添加代理配置。

搜索http-proxy-middleware json请求502,就发现了解决方案。

问题原因

在node项目中,会使用bodyParser这个库来解析post请求的参数,这个库会改写所有post请求的body,所以前端代码请求其他项目的post请求的body也会被修改。

解决办法

在代理别的项目的接口时修改body。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
app.use('/myapi', createProxyMiddleware({
target: 'http://x.x.x.x:x',
pathRewrite: (path) => path.replace("/myapi/", "/"),
on: {
proxyReq: (proxyReq, req: Request, res) => {
if (!req.body || !Object.keys(req.body).length) {
return;
}

const contentType = proxyReq.getHeader('Content-Type');
const writeBody = (bodyData: string) => {
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
};

if (contentType === 'application/json') {
writeBody(JSON.stringify(req.body));
}

if (contentType === 'application/x-www-form-urlencoded') {
writeBody(querystring.stringify(req.body));
}
},
},
}));

在这个issue参考issue中发现了解决办法,然后又在http-proxy-middleware的readme中发现了相关记载。

image.png