搭建代理服务

在网络应用中,代理服务器起着非常重要的作用。代理服务器可以作为客户端和服务器之间的中间商,帮助它们之间进行通信。在本篇文章中,我们将从零开始搭建一个简单的代理服务器。

什么时候需要使用代理服务器

在开发过程中,可能会遇到 后端可能有多个服务器,不同的 ip 和端口号,而且还不支持跨域(不支持本地跨域),这时候就需要使用代理了

搭建代理的方式

  • 使用 nginx 搭建代理
  • 使用 webpack、vite 等工具
  • 使用后端语言搭建,例如 Node.js、Python 等

使用nginx搭建代理服务

配置一个简单的代理服务

修改 nginx 的配置文件

conf 复制代码
server {  
    listen 80;  
    server_name example.com;  
  
    location / {  
    }  
  
    location /api1 {  
        proxy_pass http://backend_server;  
        add_header 'Access-Control-Allow-Origin' '*';  
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';  
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';  
    }
}

在上面的配置中,我们将所有路径(/api)的请求代理到名为backend_server的后端服务器。proxy_pass指令定义了代理的目标地址,proxy_set_header指令用于设置请求头信息。

此外,我们使用add_header指令添加了跨域相关的响应头,允许来自所有来源(*)的跨域请求,并允许使用 GETPOSTOPTIONS 方法。我们还允许某些常见的请求头,这些请求头在跨域请求中通常会使用。

配置完成后, 检查NGINX配置文件的语法是否正确

bash 复制代码
nginx -t

重启 nginx 服务

bash 复制代码
nginx -s reload

配置多个端口号

conf 复制代码
http {  
    server {  
        listen 80;
        server_name example.com;
  
        location / {  
            proxy_pass http://backend_server_1;
        }
    }
    server {  
        listen 81;
        server_name example.com;
  
        location / {  
            proxy_pass http://backend_server_2;
        }
    }
}

使用 Koa 搭建代理服务

这里将完整代码放在了 github 上(点击这里查看),可以直接下载使用

安装下依赖

bash 复制代码
npm i koa、koa2-connect、http-proxy-middleware @koa/cors

首先导入了 koa、koa2-connect、http-proxy-middleware、cors(跨域资源共享),我们代理的服务是可配置的,这里我使用了 dotenv(管理环境变量)

我们要使用 typescript 来开发,下面安装 typescript 相关依赖

bash 复制代码
npm i typescript ts-node @types/koa -D

如果使用了 Bun ,可以不用安装 typescript 相关的依赖,因为 Bun 可以直接运行 ts 文件

设计

.env 文件中,用户可以

  • 方式1,指定要代理的域名(或ip)和端口号,即 HOST 和 PORT
    • 域名必须指定一个,且只能指定一个。
    • 端口号可以指定一个或多个,指定多个时要代理多个端口
  • 方式1,直接指定完整的域名+端口号。这里端口号不能相同
  • 指定 BASE,代理的基础路径,如 /api

注意: 因为相同端口号只能开启一个服务,多个域名必须使用不同端口才能使用代理服务。可以使用第二种方式

.env 复制代码
HOST=http://10.14.80.100
PORT=10027,10026

创建服务

在package.json 配置启动命令, 通过 npm start 来启动

json 复制代码
{
  "scripts": {
    "start": "ts-node app"
  }
 }

json 复制代码
{
  "scripts": {
    "start": "bun app.ts"
  }
 }

编写代理服务,每调用一次createApp 就代理一个新的服务

ts 复制代码
import Koa from 'koa'
import connect from 'koa2-connect'
import { createProxyMiddleware } from 'http-proxy-middleware'
import cors from '@koa/cors'

function createApp(app: Koa, target: string, port: string | number) {
  const proxy = createProxyMiddleware({
    target,
    changeOrigin: true
  })
  // 支持跨域
  app.use(cors())
  // 将 /api 的请求代理到 target 
  app.use(async (ctx, next) => {
    if (ctx.path.startsWith(BASE)) {
      await connect(proxy)(ctx, next)
    } else {
      await next()
    }
  })
  
  // 启动指定 port 服务
  app.listen(port, () => {
    console.log(`Proxy server is running on  \x1b[92mhttp://localhost:${port} \x1b[0m`)
  })
}

接下来编写接收 .env 文件的配置

ts 复制代码
import * as dotenv from 'dotenv'

dotenv.config()
const BASE = process.env['BASE'] || '/api'
const TARGETS = process.env['TARGET']?.trim()?.split(',')

if (TARGETS?.length) {
  TARGETS.forEach((target) => {
    const app = new Koa()
    target = target.trim()
    if(target){
      const port = target.split(':')[2]
      createApp(app, target, port)
    }
  })
} else {
  const hosts = process.env['PORT']?.split(',') || [8080]
  const host = process.env['HOST']
  if (!host) {
    throw new Error('请在 .env 文件中配置 HOST')
  }
  hosts.forEach((port) => {
    const app = new Koa()
    createApp(app, `${host.trim()}:${port.trim()}`, port.trim())
  })
}
相关推荐
小白小白从不日白3 分钟前
react 组件通讯
前端·react.js
Redstone Monstrosity20 分钟前
字节二面
前端·面试
东方翱翔28 分钟前
CSS的三种基本选择器
前端·css
Fan_web1 小时前
JavaScript高级——闭包应用-自定义js模块
开发语言·前端·javascript·css·html
yanglamei19621 小时前
基于GIKT深度知识追踪模型的习题推荐系统源代码+数据库+使用说明,后端采用flask,前端采用vue
前端·数据库·flask
千穹凌帝1 小时前
SpinalHDL之结构(二)
开发语言·前端·fpga开发
Adolf_19931 小时前
Flask-JWT-Extended登录验证, 不用自定义
后端·python·flask
dot.Net安全矩阵1 小时前
.NET内网实战:通过命令行解密Web.config
前端·学习·安全·web安全·矩阵·.net
叫我:松哥1 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
海里真的有鱼1 小时前
Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
开发语言·后端·rabbitmq