如何用 express 实现一个简单的正向代理模块

2,517 阅读3分钟

前言

隔壁的前端妹子,碰到个 webpack proxy 的问题,不论怎么配置,发请求始终返回 404,无奈向我求助,本以为是个大显身手的好机会,没成想无情的翻了车。

查了文档才知道,原来在 proxy 的配置中,必须要配置changeOrigin: true,才可以正常使用代理

为找回男人曾失去的尊严!所以决定研究一下这个 proxy 到底是如何实现的

什么是 proxy

我这里所说的 proxy 是 webpack 的代理模块

通过配置 proxy,我们就可以绕开浏览器同源的限制,自由的向目标服务器发送请求

不过要是你们的后端大佬愿意帮你跨域,那么请忽略以下内容

正文

首先我在网上找到一个现成的代理模块的库http-proxy-middleware

使用这个库,我们可以很轻松的实现一个代理功能,这里粘贴一下文档,并附上原文地址

// javascript
 
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
 
const app = express();
 
app.use('/api', createProxyMiddleware({ target: 'http://www.example.org', changeOrigin: true }));
app.listen(3000);
 
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar

该库基于 express ,使用 http-proxy-middleware 中的 createProxyMiddleware 方法,配置代理的目标服务器地址,及配置项,从而实现代理。本文此处不是重点,有兴趣的可以去看一下原文

戳我去原文

使用 node 内置的 http 模块实现代理

此处划下重点!!!

由于只是浏览器不允许非同源的地址进行数据交互,而对于服务器的请求则没有类似的限制。那么我在本地的前端项目服务器上向另外一个服务器发送请求,拿到 response 后再由前端服务器,将此 response 返还给页面不就可以了吗?

思路有了,那么接下来我们开始动手写,对 express 不太熟悉的同学可以先去看看 express 的文档

目录结构如下:

- node_modules
- package.json
- index.js
- proxy.json
- targetServer.js

开始!!!

  • 创建一个目标服务器, port 为 3001
// targetServer.js

const express = require('express');
const app = express();

app.get('/api', (req, res) => {
  res.send('<p>这里是目标服务器</p>')
})

app.listen(3001, err => {
  if(err) {
    console.log(err)
  }
  console.log('listen on 3001 and server is running')
});
  • 创建前端服务, port 为 3000
// index.js

const express = require('express')

const app = express()

app.listen(3000, err => {
  if (err) {
    console.log(err)
  }
  console.log('listen on 3000 and server is running')
});
  • 创建代理配置文件
// proxyConfig.json

{
  "/api": {
    "target": "http://localhost:3001"
  }
}
  • 在 index.js 中引入配置文件
// index.js

const express = require('express')

const app = express()

const proxyConfig = require('./proxy.json')

app.listen(3000, err => {
  if (err) {
    console.log(err)
  }
  console.log('listen on 3000 and server is running')
});
  • 引入 http 模块,开始实现代理
const http = require('http')
const express = require('express')

const app = express()

const proxyConfig = require('./proxy.json')

for (let proxy in proxyConfig) {
  app.get(proxy, (req, res) => {
    const originalUrl = req.originalUrl
    http.get(proxyConfig[proxy].target + originalUrl, req => {
      let html = '';
      req.on('data', function (data) {
        html += data;
      });
      req.on('end', function () {
        res.send(html)
      });
    })
  })
}

app.listen(3000, err => {
  if (err) {
    console.log(err)
  }
  console.log('listen on 3000 and server is running')
});
  • 启动 index.js ,targetServer.js
node index.js

node targetServer.js

到这里

你就可以访问 localhost:3000/api,返回 localhost:3001/api 的数据啦