axios + Express + http-proxy 发送post请求后台无法接收body问题修复方法
技术背景:vue项目中使用axios调用接口,前端使用Express作为服务器,http-proxy作为api代理服务器。问题描述:axios发送get请求没有问题,但是当调用post和put请求并携带body体时,请求一直卡在pending状态,后台反馈没有收到body数据,但是我在expess的proxy代理中debugger是能够看到req.body的。原因分析:baidu+goog...
技术背景:vue项目中使用axios调用接口,前端使用Express作为服务器,http-proxy作为api代理服务器。
问题描述:axios发送get请求没有问题,但是当调用post和put请求并携带body体时,请求一直卡在pending状态,后台反馈没有收到body数据,但是我在expess的proxy代理中debugger是能够看到req.body的。
原因分析:baidu+google,加上查看http-proxy的GitHub issues,确定是因为axios默认以application/json形式发送请求数据,而Express服务中,我们又使用了BodyParser,从而导致请求的body数据被json序列化两次,后台接收到的body数据不符合格式。
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
解决办法:
一、URLSearchParams API
在浏览器环境,你可以使用 URLSearchParams API,但是并不是所有的浏览器都支持URLSearchParams 。不推荐使用。
const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);
二、querystring/qs
1、axios发送请求时,对body数据进行序列化
const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));
// Or in another way (ES6),
import qs from 'qs';
const data = { 'bar': 123 };
const options = {
method: 'POST',
data: qs.stringify(data),
url,
};
axios(options);
2、利用axios拦截器,拦截请求并对body数据进行序列化
import qs from "qs";
// ...
_axios.interceptors.request.use(
function(config) {
// Do something before request is sent
config.data = qs.stringify(config.data);
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
}
);
三、express服务端处理
假设http-proxy代理了所有以“/api”开头的请求,后台接收application/json形式数据
1、axios已经对参数进行了json序列化,可以不使用bodyparser
var bodyParser = require('body-parser');
// 使用正则表达式过滤/api开头的请求
app.use(/^(?!\/api)/, bodyParser.json());
app.use(/^(?!\/api)/, bodyParser.urlencoded({ extended: true }));
2、http-proxy拦截器,对body参数进行序列化处理
var proxy = require('http-proxy');
proxy.on('proxyReq', function(proxyReq, req) {
//...
if (req.body && req.complete) {
var bodyData = JSON.stringify(req.body);
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
}
});
//...
route.use(function(req, res, next) {
proxy.web(req, res)
})
更多推荐
所有评论(0)