http-proxy-middleware 简介
http-proxy-middleware 是 Node.js 生态中最流行的代理中间件,npm 周下载量极高,支持 Express、Connect、NestJS 等多种框架。它的核心功能是将匹配特定路径的请求代理到目标服务器。
版本注意:v2 到 v3 有 Breaking Changes,主要在 options 接口的命名方式上——v2 使用下划线命名(changeOrigin),v3 改为小驼峰。使用时注意保持大版本号一致。
在 NestJS 中集成反向代理
pnpm install http-proxy-middleware
bash
// proxy.controller.ts 或 main.ts 中
import { Controller, All, Req, Res, Next } from '@nestjs/common'
import { createProxyMiddleware } from 'http-proxy-middleware'
@Controller('api')
export class ProxyController {
private proxy = createProxyMiddleware({
target: 'https://api.openai.com',
changeOrigin: true,
pathRewrite: { '^/api': '' }, // 移除 /api 前缀
on: {
proxyRes: (proxyRes, req, res) => {
// 可以在这里拦截和记录响应数据
console.log('代理响应:', proxyRes.statusCode)
},
proxyReq: (proxyReq, req, res) => {
// 可以在这里修改请求头,添加认证信息
proxyReq.setHeader('Authorization', 'Bearer YOUR_API_KEY')
}
}
})
@All('*')
handleProxy(@Req() req, @Res() res, @Next() next) {
this.proxy(req, res, next)
}
}
typescript
访问 localhost:3000/api/v1/chat/completions 会被代理到 https://api.openai.com/v1/chat/completions。
关键配置项
| 配置项 | 说明 |
|---|---|
target | 代理目标地址 |
changeOrigin | 是否修改请求头中的 Host 为目标地址 |
pathRewrite | 路径重写规则 |
on.proxyRes | 拦截响应数据的回调 |
on.proxyReq | 修改请求的回调 |
timeout | 代理请求超时时间 |
ws | 是否代理 WebSocket 请求 |
前置代理(Forward Proxy / Agent)
当目标服务器无法直接访问时(如国内访问 OpenAI API),需要通过前置代理转发请求。http-proxy-middleware 的生态中提供了多种 Agent:
| Agent | 协议 | 安装包 |
|---|---|---|
https-proxy-agent | HTTPS | https-proxy-agent |
http-proxy-agent | HTTP | http-proxy-agent |
socks-proxy-agent | SOCKS5 | socks-proxy-agent |
pac-proxy-agent | PAC 自动配置 | pac-proxy-agent |
使用 HTTPS 前置代理
pnpm install https-proxy-agent
bash
import { HttpsProxyAgent } from 'https-proxy-agent'
import { createProxyMiddleware } from 'http-proxy-middleware'
const agent = new HttpsProxyAgent('http://your-proxy-server:7890')
const proxy = createProxyMiddleware({
target: 'https://api.openai.com',
changeOrigin: true,
pathRewrite: { '^/api': '' },
agent: agent, // 通过前置代理转发
})
typescript
使用 SOCKS5 前置代理
pnpm install socks-proxy-agent
bash
import { SocksProxyAgent } from 'socks-proxy-agent'
const agent = new SocksProxyAgent('socks5://your-proxy-server:1080')
const proxy = createProxyMiddleware({
target: 'https://api.openai.com',
changeOrigin: true,
pathRewrite: { '^/api': '' },
agent: agent,
})
typescript
正向代理 vs 反向代理
理解两种代理的区别是本节的核心概念:
正向代理(Forward Proxy / 前置代理):代理的是客户端。客户端知道目标服务器是谁,但目标服务器不知道真正的客户端是谁。典型场景:VPN、科学上网。用户的请求先到代理服务器,代理服务器再转发到目标。
反向代理(Reverse Proxy):代理的是服务端。客户端不知道真正的服务器是谁,只知道反向代理服务器的地址。典型场景:Nginx 负载均衡。用户请求到 Nginx,Nginx 转发到后端的多台服务器。
在本节的架构中,两者同时存在:
用户 -> [反向代理: NestJS + http-proxy-middleware] -> [前置代理: Agent] -> 目标API
text
- NestJS 充当反向代理,对用户隐藏了真正的目标 API
- Agent 充当正向代理,让请求能够到达原本无法直接访问的目标 API
替代方案:海外 VPS 部署
如果不想在本地配置 Agent,另一种方案是将 NestJS 应用部署到海外的 VPS(Virtual Private Server)上。在能直接访问目标 API 的服务器上运行应用,就不需要前置代理了。通过 SSH 连接到海外服务器(如 Ubuntu),确认能直接 curl https://api.openai.com,然后在上面部署应用即可。
↑