You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.7 KiB
111 lines
3.7 KiB
/** |
|
* 开发环境代理服务器 |
|
* 用于解决跨域问题和统一 API 请求 |
|
*/ |
|
|
|
const express = require('express'); |
|
const { createProxyMiddleware } = require('http-proxy-middleware'); |
|
const cors = require('cors'); |
|
|
|
const app = express(); |
|
const PORT = 8086; |
|
|
|
// 启用 CORS |
|
app.use(cors({ |
|
origin: '*', // 允许所有源,开发环境使用 |
|
credentials: true, |
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'], |
|
allowedHeaders: [ |
|
'Content-Type', |
|
'Authorization', |
|
'X-Requested-With', |
|
'Accept', |
|
// 自定义请求头 |
|
'cmdId', |
|
'datetime', |
|
'pwds', |
|
'aseqId', |
|
'nc', |
|
'apiName', |
|
'tid', |
|
'custId', |
|
'reqId', |
|
'isMobileOpen', |
|
'languageNum', |
|
'project', |
|
'platform', |
|
'checkOr', |
|
'tbc', |
|
'reqKey', |
|
'signature', |
|
'authorization', |
|
], |
|
exposedHeaders: ['cmdId', 'datetime', 'pwds', 'aseqId', 'nc', 'checkOr', 'checkor'], |
|
})); |
|
|
|
// 目标 API 服务器地址 |
|
const API_TARGET = process.env.API_TARGET || 'https://51zhh5.notbug.org'; |
|
|
|
// 代理路径列表 |
|
const PROXY_PATHS = ['/api/v2']; |
|
|
|
// 为每个路径配置代理 |
|
PROXY_PATHS.forEach((path) => { |
|
app.use( |
|
path, |
|
createProxyMiddleware({ |
|
target: API_TARGET, |
|
changeOrigin: true, |
|
secure: false, // 如果目标服务器使用自签名证书,设置为 false |
|
pathRewrite: (pathStr, req) => { |
|
// Express 会自动去掉匹配的前缀,所以需要加回来 |
|
const fullPath = path + pathStr; |
|
console.log(`[Proxy] Path rewrite: ${pathStr} → ${fullPath}`); |
|
return fullPath; |
|
}, |
|
onProxyReq: (proxyReq, req, res) => { |
|
const fullPath = path + req.url; |
|
console.log(`[Proxy] ${req.method} ${fullPath} → ${API_TARGET}${fullPath}`); |
|
}, |
|
onProxyRes: (proxyRes, req, res) => { |
|
const fullPath = path + req.url; |
|
console.log(`[Proxy] ${req.method} ${fullPath} ← ${proxyRes.statusCode}`); |
|
|
|
// 确保 CORS 头被正确设置 |
|
res.setHeader('Access-Control-Allow-Origin', '*'); |
|
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH'); |
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, Accept, cmdId, datetime, pwds, aseqId, nc, apiName, tid, custId, reqId, isMobileOpen, languageNum, project, platform, checkOr, tbc, reqKey, signature, authorization'); |
|
res.setHeader('Access-Control-Expose-Headers', 'cmdId, datetime, pwds, aseqId, nc, checkOr, checkor'); |
|
res.setHeader('Access-Control-Allow-Credentials', 'true'); |
|
}, |
|
onError: (err, req, res) => { |
|
console.error('[Proxy Error]', err.message); |
|
res.status(500).json({ |
|
error: 'Proxy Error', |
|
message: err.message, |
|
}); |
|
}, |
|
}) |
|
); |
|
}); |
|
|
|
// 健康检查 |
|
app.get('/health', (req, res) => { |
|
res.json({ |
|
status: 'ok', |
|
proxy: API_TARGET, |
|
timestamp: new Date().toISOString(), |
|
}); |
|
}); |
|
|
|
app.listen(PORT, () => { |
|
console.log(` |
|
╔════════════════════════════════════════════════════════╗ |
|
║ Proxy Server Running ║ |
|
╠════════════════════════════════════════════════════════╣ |
|
║ Local: http://localhost:${PORT} ║ |
|
║ Target: ${API_TARGET.padEnd(40)} ║ |
|
║ Health: http://localhost:${PORT}/health ║ |
|
╚════════════════════════════════════════════════════════╝ |
|
`); |
|
});
|
|
|