fix(desktop): /api 反代保留完整路径(修复 Express 挂载剥前缀致后端 404)
This commit is contained in:
+30
-26
@@ -9,33 +9,37 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||
function createServer({ staticDir, backendUrl }) {
|
||||
const app = express();
|
||||
|
||||
app.use(
|
||||
'/api',
|
||||
createProxyMiddleware({
|
||||
target: backendUrl,
|
||||
changeOrigin: true,
|
||||
ws: false,
|
||||
xfwd: true,
|
||||
// http-proxy 侧不设响应/套接字超时(SSE 看门狗 1200s / 上传 600s 由后端自断)
|
||||
proxyTimeout: 0,
|
||||
timeout: 0,
|
||||
on: {
|
||||
error: (err, req, res) => {
|
||||
// 后端不可达时返回结构化 502 信封(对齐前端 http.js 的错误契约),避免进程崩溃。
|
||||
// 注意:http-proxy 的 error 事件里 res 可能是 net.Socket(连接失败),需防御式判断。
|
||||
if (!res || typeof res.writeHead !== 'function') return;
|
||||
if (res.headersSent) return res.end();
|
||||
res.writeHead(502, { 'Content-Type': 'application/json; charset=utf-8' });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
ok: false,
|
||||
error: { code: 'NETWORK', message: '后端不可达', degraded: false },
|
||||
})
|
||||
);
|
||||
},
|
||||
const proxy = createProxyMiddleware({
|
||||
target: backendUrl,
|
||||
changeOrigin: true,
|
||||
ws: false,
|
||||
xfwd: true,
|
||||
// http-proxy 侧不设响应/套接字超时(SSE 看门狗 1200s / 上传 600s 由后端自断)
|
||||
proxyTimeout: 0,
|
||||
timeout: 0,
|
||||
on: {
|
||||
error: (err, req, res) => {
|
||||
// 后端不可达时返回结构化 502 信封(对齐前端 http.js 的错误契约),避免进程崩溃。
|
||||
// 注意:http-proxy 的 error 事件里 res 可能是 net.Socket(连接失败),需防御式判断。
|
||||
if (!res || typeof res.writeHead !== 'function') return;
|
||||
if (res.headersSent) return res.end();
|
||||
res.writeHead(502, { 'Content-Type': 'application/json; charset=utf-8' });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
ok: false,
|
||||
error: { code: 'NETWORK', message: '后端不可达', degraded: false },
|
||||
})
|
||||
);
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
// 只代理 /api,并保留完整路径(/api/xxx → backend/api/xxx)。
|
||||
// 注意:不能写成 app.use('/api', proxy) —— Express 会剥掉 /api 前缀,导致后端收到 /xxx 而 404。
|
||||
app.use((req, res, next) => {
|
||||
if (req.path.startsWith('/api')) return proxy(req, res, next);
|
||||
next();
|
||||
});
|
||||
|
||||
// 静态托管 + SPA fallback(前端无 vue-router,单页;仍兜底到 index.html)
|
||||
app.use(express.static(staticDir));
|
||||
|
||||
Reference in New Issue
Block a user