mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-26 02:04:37 +08:00
fix(cli): add /_proxy/chatlab.fun reverse proxy for web mode
在 Web 生产模式(chatlab start)下,浏览器无法直连 chatlab.fun(CORS 限制), 导致首页底部社交链接(如小红书)及云端助手/技能预设拉取失败。 Vite dev proxy 已有对应配置,但生产 Fastify server 缺少该代理,现补全。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
d1637b41b8
commit
b96ec69730
2 files changed
+47
No files matched your search
@@ -25,6 +25,7 @@ import { registerWebRoutes } from './routes/web'
|
||||
import { registerNlpRoutes } from './routes/nlp'
|
||||
import { registerAiRoutes } from './routes/ai'
|
||||
import { registerPreferencesRoutes } from './routes/preferences'
|
||||
import { registerProxyRoutes } from './routes/proxy'
|
||||
import { initServerAiLogger, closeServerAiLogger } from '../ai/logger'
|
||||
import { initSync, cleanupSync } from '../sync'
|
||||
import { resolveCliPath } from '../paths'
|
||||
@@ -140,6 +141,10 @@ export async function startHttpServer(options?: HttpServerOptions): Promise<{
|
||||
|
||||
if (options?.webRoot && fs.existsSync(options.webRoot)) {
|
||||
setWebMode(true)
|
||||
// 注册反向代理:将 /_proxy/chatlab.fun/* 转发至 https://chatlab.fun,
|
||||
// 行为与 vite dev proxy 一致,解决浏览器 CORS 问题(见 vite.web.config.mts:138-144)。
|
||||
// 必须在 @fastify/static 之前注册,确保显式路由优先于静态文件/SPA fallback。
|
||||
registerProxyRoutes(server)
|
||||
const fastifyStatic = await import('@fastify/static')
|
||||
await server.register(fastifyStatic.default, {
|
||||
root: options.webRoot,
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 反向代理路由 — /_proxy/chatlab.fun/*
|
||||
*
|
||||
* 在 Web 生产模式(chatlab start)下,将 /_proxy/chatlab.fun/* 代理到
|
||||
* https://chatlab.fun,行为与 vite.web.config.mts 中的 dev proxy 保持一致,
|
||||
* 以解决浏览器 CORS 限制。
|
||||
*
|
||||
* 目标 host 硬编码为 https://chatlab.fun,不允许外部指定,避免开放代理风险。
|
||||
*/
|
||||
|
||||
import type { FastifyInstance } from 'fastify'
|
||||
|
||||
const PROXY_TARGET = 'https://chatlab.fun'
|
||||
|
||||
export function registerProxyRoutes(server: FastifyInstance): void {
|
||||
server.get<{ Params: { '*': string } }>('/_proxy/chatlab.fun/*', async (request, reply) => {
|
||||
const subPath = request.params['*'] ?? ''
|
||||
const queryString = new URLSearchParams(
|
||||
request.query as Record<string, string>,
|
||||
).toString()
|
||||
const targetUrl = queryString
|
||||
? `${PROXY_TARGET}/${subPath}?${queryString}`
|
||||
: `${PROXY_TARGET}/${subPath}`
|
||||
|
||||
try {
|
||||
const upstream = await fetch(targetUrl, {
|
||||
headers: { Accept: request.headers.accept ?? '*/*' },
|
||||
signal: AbortSignal.timeout(10_000),
|
||||
})
|
||||
|
||||
const contentType = upstream.headers.get('content-type') ?? 'application/octet-stream'
|
||||
const body = Buffer.from(await upstream.arrayBuffer())
|
||||
|
||||
reply.code(upstream.status).header('content-type', contentType).send(body)
|
||||
} catch (err) {
|
||||
reply.code(502).send({
|
||||
error: 'Proxy error',
|
||||
message: err instanceof Error ? err.message : String(err),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user