Express使用http-proxy-middleware代理请求

386 阅读2分钟

Express代理本地请求

一般前端使用的都是webpack 或者 vite 这种成熟构建工具,代理其实只需要配置一下就好了,但是有些情况可能需要搭配koa或者express去代理本地请求,像这种情况,一般会搭配http-proxy-middleware 一起使用,接下来介绍一下express使用http-proxy-middleware 代理本地请求到指定域名请求的一种方法

前置环境搭建

# 配置express最轻量的启动脚本服务

var express = require('express');
var { createProxyMiddleware } = require('http-proxy-middleware');
var app = express();
var port = process.env.PORT || config.dev.port;

module.exports = app.listen(port, function(err) {
  if (err) {
    console.log(err);
    return;
  }
  console.log('Listening at http://localhost:' + port + '\n');
});


使用 http-proxy-middleware 配置代理

1. 安装 http-proxy-middleware

npm install --save-dev http-proxy-middleware

2. 配置middleware

var express = require('express');
var { createProxyMiddleware } = require('http-proxy-middleware');
var app = express();
var port = process.env.PORT || config.dev.port;

# 如果env需要proxy,那就代理到指定环境
if (process.env.proxy) {
  app.use(createProxyMiddleware({
    // 要代理的目标地址
    target: process.env.proxy,
    changeOrigin: true,
    secure: false,
    logLevel: 'debug',
    timeout: 5000,
    proxyTimeout: 6000,
    // pathFilter 可以配置那些地址可以走代理
    // 这里可以是 string,string[], (path):Boolean 等等,具体可以按照官方的来写就好了
    pathFilter: pathname => {
      console.log('pathname :>> ', pathname);
      return !(pathname.match('html') || pathname === '/');
    },
    headers: { referer: process.env.proxy },
    logger: console,
    on: {
      proxyReq: (proxyReq, req, res) => {
        console.log('proxyReq :>> ', proxyReq.path);
        proxyReq.setHeader('referer', process.env.proxy);
      },
      error: (err, req, res) => {
        console.log('error', err);
      }
    }

  }));
}

module.exports = app.listen(port, function(err) {
  if (err) {
    console.log(err);
    return;
  }
  console.log('Listening at http://localhost:' + port + '\n');
});


到此简单的代理就配置完成了

但是遇到一个问题,接下来简单描述一下,如果有遇到的朋友可以参考一下

  1. 现象:get请求ok,post请求无返回会报错
  2. 排查:bodyParser 导致的代理转发带有 body 数据的 post 请求会失败
  3. 结论:去掉中间件 bodyParser

这里贴一下完整的代码,如果大家碰到相似问题可以试一下,希望可以帮到类似问题的朋友


var express = require('express');
var webpack = require('webpack');
var config = require('../config');
var { createProxyMiddleware } = require('http-proxy-middleware');
var webpackConfig = process.env.NODE_ENV === 'testing' ? require('./webpack.prod.conf') : require('./webpack.dev.conf');
var { mock } = require('./dev-api');
var app = express();
var compiler = webpack(webpackConfig);
var port = process.env.PORT || config.dev.port;

var devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: webpackConfig.output.publicPath,
  stats: {
    colors: true,
    chunks: false
  }
});

var hotMiddleware = require('webpack-hot-middleware')(compiler, { log: () => {} });

// force page reload when html-webpack-plugin template changes
// 当html-webpack-plugin模版改变时重新加载页面
compiler.plugin('compilation', function(compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function(data, cb) {
    hotMiddleware.publish({ action: 'reload' });
    cb();
  });
});

// serve webpack bundle output
app.use(devMiddleware);
app.use(hotMiddleware);
app.get('/', (_, res) => res.redirect('/html/index.html'));

// var proxyConfig = config.dev.proxy;
// // 使用代理数据
// if (proxyConfig.open) {
//   // 解析req.body
//   var bodyParser = require('body-parser');
//   // parse application/x-www-form-urlencoded
//   app.use(bodyParser.urlencoded({ extended: true }));
//   // parse application/json
//   app.use(bodyParser.json());
// }

if (process.env.proxy) {
  app.use(createProxyMiddleware({
    target: process.env.proxy,
    changeOrigin: true,
    secure: false,
    logLevel: 'debug',
    timeout: 5000,
    proxyTimeout: 6000,
    pathFilter: pathname => {
      console.log('pathname :>> ', pathname);
      return !(pathname.match('html') || pathname === '/');
    },
    headers: { referer: process.env.proxy },
    logger: console,
    on: {
      proxyReq: (proxyReq, req, res) => {
        console.log('proxyReq :>> ', proxyReq.path);
        proxyReq.setHeader('referer', process.env.proxy);
      },
      error: (err, req, res) => {
        console.log('error', err);
        res.writeHead(504, {
          code: 504,
          message: 'Gateway Timeout'
        });
      }
    }

  }));
} else {
  // 使用mock数据
  app.use(mock);
}

module.exports = app.listen(port, function(err) {
  if (err) {
    console.log(err);
    return;
  }
  console.log('Listening at http://localhost:' + port + '\n');
});


写在最后

因为时间问题,我没有研究具体原因,知道的同学可以评论区科普一下,