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+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)
  })

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值