diff --git a/frontend/package.json b/frontend/package.json index be0f8fa..36059e2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", - "preview": "vite preview --port 5173" + "preview": "vite preview --port 8888" }, "dependencies": { "@ant-design/icons": "^5.4.0", diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 331a052..905db18 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -32,39 +32,31 @@ export default defineConfig(({ mode }) => { target: proxyTarget, changeOrigin: true, ws: true, - // 为 SSE 透传加固:禁用超时并保持连接 + }, + '/sse': { + target: 'http://127.0.0.1:8866', + changeOrigin: true, + ws: false, proxyTimeout: 0, timeout: 0, headers: { 'Connection': 'keep-alive' }, - // 关键:在 dev 代理层面禁止缓冲/缓存,强制以 chunk 方式向浏览器侧回传,避免一次性聚合 + rewrite: (path: string) => path.replace(/^\/sse/, '/api'), configure: (proxy: any) => { - // 移除 Accept-Encoding,避免后端压缩导致中间件缓冲 - proxy.on('proxyReq', (proxyReq: any, req: any) => { - const url: string = req?.url || '' - if (url.includes('/run/stream')) { - try { - if (typeof proxyReq.removeHeader === 'function') proxyReq.removeHeader('accept-encoding') - proxyReq.setHeader('accept', 'text/event-stream') - proxyReq.setHeader('connection', 'keep-alive') - } catch {} - } - }) - - proxy.on('proxyRes', (proxyRes: any, req: any, res: any) => { - const url: string = req?.url || '' - const ct: string = String(proxyRes.headers?.['content-type'] || '') - const isSse = url.includes('/run/stream') || ct.includes('text/event-stream') - if (!isSse) return + proxy.on('proxyReq', (proxyReq: any) => { + try { + if (typeof proxyReq.removeHeader === 'function') proxyReq.removeHeader('accept-encoding') + proxyReq.setHeader('accept', 'text/event-stream') + proxyReq.setHeader('connection', 'keep-alive') + } catch {} + }) + proxy.on('proxyRes', (proxyRes: any, _req: any, res: any) => { try { - // 直接改写后端返回头,确保为 SSE 且无长度/压缩 proxyRes.headers['content-type'] = 'text/event-stream; charset=utf-8' proxyRes.headers['cache-control'] = 'no-cache' proxyRes.headers['pragma'] = 'no-cache' proxyRes.headers['x-accel-buffering'] = 'no' delete proxyRes.headers['content-length'] delete proxyRes.headers['content-encoding'] - - // 同步确保 devServer 给浏览器的头一致,并尽早发送 res.setHeader('Content-Type', 'text/event-stream; charset=utf-8') res.setHeader('Cache-Control', 'no-cache') res.setHeader('Pragma', 'no-cache') @@ -75,6 +67,13 @@ export default defineConfig(({ mode }) => { } catch {} }) } + }, + // 新增:WS 独立代理前缀,将 /ws/* 重写到后端 8855 的 /api/*(握手走 WS) + '/ws': { + target: 'http://127.0.0.1:8855', + changeOrigin: true, + ws: true, + rewrite: (path: string) => path.replace(/^\/ws/, '/api'), } } }