From 6ea1f28940766c3c2f9e6a03c9c5ebf13c415f57 Mon Sep 17 00:00:00 2001 From: YANG JIANKUAN Date: Thu, 3 Sep 2026 17:38:38 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8F=8D=E4=BB=A3=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E4=B8=8B=E6=8C=89=20X-Forwarded=20=E5=A4=B4=E8=BF=98=E5=8E=9F?= =?UTF-8?q?=E8=AE=A2=E9=98=85=E5=9F=BA=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 部署在 nginx 之后时 Node 只看到明文 http 与内网 Host,Surge 的 #!MANAGED-CONFIG 与 Clash 的 provider URL 会指向不可达地址。 读取 X-Forwarded-Proto/X-Forwarded-Host 还原外部 origin。 Co-Authored-By: Claude Opus 4.6 --- server/src/routes/sub.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/server/src/routes/sub.ts b/server/src/routes/sub.ts index ecc3ce9..8f2d11a 100644 --- a/server/src/routes/sub.ts +++ b/server/src/routes/sub.ts @@ -34,9 +34,18 @@ function touchToken(id: string, count: number) { .run(); } -/** 订阅 URL 基址:直接取本次请求的 origin——客户端能请求到这里,origin 就一定可达 */ -function baseUrl(c: { req: { url: string } }): string { - return new URL(c.req.url).origin; +/** + * 订阅 URL 基址:取本次请求的 origin——客户端能请求到这里,origin 就一定可达。 + * 部署在 nginx 等反代之后时,Node 只看到明文 http 与内网 Host,需读 X-Forwarded-Proto/Host 还原外部地址, + * 否则 Surge 的 #!MANAGED-CONFIG 与 Clash 的 provider URL 会指向不可达的 http://127.0.0.1。 + */ +function baseUrl(c: { req: { url: string; header: (name: string) => string | undefined } }): string { + const url = new URL(c.req.url); + const proto = c.req.header('x-forwarded-proto')?.split(',')[0].trim(); + const host = c.req.header('x-forwarded-host')?.split(',')[0].trim(); + if (proto) url.protocol = `${proto}:`; + if (host) url.host = host; + return url.origin; } export const subRoute = new Hono()