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

/**
* 开发环境代理服务器
* 用于解决跨域问题和统一 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/v1', '/api/v2', '/api/v3'];
// 为每个路径配置代理
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 ║
╚════════════════════════════════════════════════════════╝
`);
});