A powerful HTTP proxy middleware plugin for Egg.js with TypeScript support
中文文档 | English
Built on top of http-proxy-middleware.
📝 Changelog | 📦 Examples | 🐛 Issues
| Feature | Description |
|---|---|
| 📁 File Upload | Built-in multipart/form-data support |
| 🔧 Custom Matching | Function-based path matching |
| 🔄 ctx Passing | Access Egg.js context in callbacks |
| 📘 TypeScript | Built-in type definitions |
| 🔌 WebSocket | WS proxy support |
| ✏️ Path Rewrite | Flexible rewrite rules |
| 🛡️ Error Handling | Custom error callbacks |
| Dependency | Version |
|---|---|
| Node.js | >= 14.0.0 |
| Egg.js | >= 3.0.0 |
npm i egg-http-proxy-plus
# or
pnpm add egg-http-proxy-plus
# or
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
# Proxies to http://backend.example.com/api/users// Object form
exports.httpProxyPlus = {
'/api': 'http://backend.example.com',
'/v1': {
target: 'http://backend.example.com',
pathRewrite: { '^/v1': '/api/v1' }
}
}
// Array form
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': '' } // Remove /api prefix
}
}
// /api/users -> http://backend.example.com/usersexports.httpProxyPlus = [
{
// Match GET requests only
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'
}| Property | Type | Required | Description |
|---|---|---|---|
origin |
string | string[] | Function |
✓ | Path pattern to match |
options |
string | ExtendedProxyOptions |
✓ | Proxy options or target URL |
| Property | Type | Required | Description |
|---|---|---|---|
target |
string |
✓ | Target URL |
pathRewrite |
object |
Path rewrite rules | |
changeOrigin |
boolean |
Change origin header (default: false) | |
onProxyReq |
Function |
Request callback (4th arg: ctx) | |
onProxyRes |
Function |
Response callback (4th arg: ctx) | |
onError |
Function |
Error callback | |
ws |
boolean |
WebSocket proxy (default: false) | |
proxyTimeout |
number |
Timeout in milliseconds |
For more options, see http-proxy-middleware docs.
Built-in type definitions:
// 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
}How to proxy file uploads?
Built-in support, no extra configuration needed.
How are POST request bodies handled?
The plugin automatically handles rawBody for proper forwarding.
How to debug proxy requests?
onProxyReq(proxyReq, req, res, ctx) {
console.log('[Proxy]', req.method, req.url, '->', proxyReq.path)
}
onProxyRes(proxyRes, req, res) {
console.log('[Response]', proxyRes.statusCode)
}How to skip certain requests?
Return false in custom matching function:
origin(pathname, req) {
if (pathname === '/health') return false
return pathname.startsWith('/api')
}Contributions are welcome! Please feel free to submit a Pull Request.