在网络应用中,代理服务器起着非常重要的作用。代理服务器可以作为客户端和服务器之间的中间商,帮助它们之间进行通信。在本篇文章中,我们将从零开始搭建一个简单的代理服务器。
什么时候需要使用代理服务器
在开发过程中,可能会遇到 后端可能有多个服务器,不同的 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
指令添加了跨域相关的响应头,允许来自所有来源(*
)的跨域请求,并允许使用 GET
、 POST
和 OPTIONS
方法。我们还允许某些常见的请求头,这些请求头在跨域请求中通常会使用。
配置完成后, 检查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())
})
}