功能强大的 Egg.js HTTP 代理中间件插件
English | 中文
基于 http-proxy-middleware 构建。
| 特性 | 说明 |
|---|---|
| 📁 文件上传代理 | 内置处理 multipart/form-data |
| 🔧 自定义匹配 | 支持函数式路径匹配 |
| 🔄 ctx 透传 | 回调函数可访问 Egg.js 上下文 |
| 📘 TypeScript | 内置类型定义文件 |
| 🔌 WebSocket | 支持 WS 代理 |
| ✏️ 路径重写 | 灵活的路径重写规则 |
| 🛡️ 错误处理 | 自定义错误回调 |
| 依赖 | 版本 |
|---|---|
| Node.js | >= 14.0.0 |
| Egg.js | >= 3.0.0 |
npm i egg-http-proxy-plus
# 或
pnpm add egg-http-proxy-plus
# 或
yarn add egg-http-proxy-plus// config/plugin.js
exports.httpProxyPlus = {
enable: true,
package: 'egg-http-proxy-plus'
}// config/config.default.js
exports.httpProxyPlus = {
'/api': 'http://backend.example.com'
}curl http://localhost:7001/api/users
# 代理到 http://backend.example.com/api/users// 对象形式
exports.httpProxyPlus = {
'/api': 'http://backend.example.com',
'/v1': {
target: 'http://backend.example.com',
pathRewrite: { '^/v1': '/api/v1' }
}
}
// 数组形式
exports.httpProxyPlus = [
{ origin: '/api', options: 'http://backend.example.com' },
{ origin: '/v1', options: { target: 'http://backend.example.com' } }
]exports.httpProxyPlus = {
'/api': {
target: 'http://backend.example.com',
pathRewrite: { '^/api': '' } // 移除 /api 前缀
}
}
// /api/users -> http://backend.example.com/usersexports.httpProxyPlus = [
{
// 仅匹配 GET 请求
origin(pathname, req) {
return pathname.startsWith('/api') && req.method === 'GET'
},
options: { target: 'http://backend.example.com' }
}
]exports.httpProxyPlus = {
'/api': {
target: 'http://backend.example.com',
onProxyReq(proxyReq, req, res, ctx) {
const token = ctx.cookies.get('access_token')
if (token) {
proxyReq.setHeader('Authorization', `Bearer ${token}`)
}
}
}
}exports.httpProxyPlus = {
'/api': {
target: 'http://backend.example.com',
onProxyRes(proxyRes, req, res, ctx) {
proxyRes.headers['x-proxy-by'] = 'egg-http-proxy-plus'
}
}
}exports.httpProxyPlus = {
'/api': {
target: 'http://backend.example.com',
onError(err, req, res) {
res.writeHead(502, { 'Content-Type': 'application/json' })
res.end(JSON.stringify({
code: 502,
message: 'Bad Gateway',
error: err.message
}))
}
}
}exports.httpProxyPlus = {
'/ws': {
target: 'ws://backend.example.com',
ws: true
}
}exports.httpProxyPlus = {
'/api/users': 'http://users-service:3001',
'/api/orders': 'http://orders-service:3002',
'/api/products': 'http://products-service:3003'
}| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
origin |
string | string[] | Function |
✓ | 路径匹配模式 |
options |
string | ExtendedProxyOptions |
✓ | 代理配置或目标 URL |
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
target |
string |
✓ | 代理目标地址 |
pathRewrite |
object |
路径重写规则 | |
changeOrigin |
boolean |
修改请求头 origin (默认 false) | |
onProxyReq |
Function |
请求回调,第4个参数为 ctx | |
onProxyRes |
Function |
响应回调,第4个参数为 ctx | |
onError |
Function |
错误回调 | |
ws |
boolean |
WebSocket 代理 (默认 false) | |
proxyTimeout |
number |
超时时间 (毫秒) |
更多选项参考 http-proxy-middleware。
插件内置类型定义:
// config/config.default.ts
import { EggAppConfig } from 'egg'
export default () => {
const config: EggAppConfig = {}
config.httpProxyPlus = {
'/api': {
target: 'http://backend.example.com',
pathRewrite: { '^/api': '' },
onProxyReq(proxyReq, req, res, ctx) {
const token = ctx.cookies.get('token')
token && proxyReq.setHeader('Authorization', token)
}
}
}
return config
}如何代理文件上传?
插件已内置处理,无需额外配置。
POST 请求体如何处理?
插件自动处理 rawBody,确保请求体正确转发。
如何调试代理?
onProxyReq(proxyReq, req, res, ctx) {
console.log('[Proxy]', req.method, req.url, '->', proxyReq.path)
}
onProxyRes(proxyRes, req, res) {
console.log('[Response]', proxyRes.statusCode)
}如何跳过某些请求?
使用自定义匹配函数返回 false:
origin(pathname, req) {
if (pathname === '/health') return false
return pathname.startsWith('/api')
}请到 GitHub Issues 提交问题或建议。