This commit is contained in:
hailin 2025-06-25 16:38:36 +08:00
parent 402779994e
commit 888bdead90
1 changed files with 62 additions and 19 deletions

View File

@ -1,49 +1,92 @@
// app/_runtime-env-provider.tsx ← 文件放 app 根,保证是 Server 组件
import { headers } from "next/headers" // ① 仅在服务器端可调用
import { useServerInsertedHTML } from "next/navigation" // ② 往最终 HTML 插入标签
// // app/_runtime-env-provider.tsx ← 文件放 app 根,保证是 Server 组件
// import { headers } from "next/headers" // ① 仅在服务器端可调用
// import { useServerInsertedHTML } from "next/navigation" // ② 往最终 HTML 插入标签
// import React from "react"
// // ------------------- 带全链路调试日志的版本 -------------------
// export function RuntimeEnvProvider({ children }: { children: React.ReactNode }) {
// /* ──────────────── 1. 解析协议 ──────────────── */
// const h = headers() // <-- Node 边界:读取当前请求头
// console.log("[RuntimeEnv] Raw headers:", Object.fromEntries(h.entries()))
// const proto =
// h.get("x-forwarded-proto") ?? // 走 Nginx / 反代时最可靠
// (h.get("host")?.includes(":443") ? "https" : "http")// 没有反代时根据端口猜
// console.log("[RuntimeEnv] Resolved protocol:", proto)
// /* ──────────────── 2. 解析主机名 ──────────────── */
// const rawHost = h.get("x-forwarded-host") ?? h.get("host")!
// console.log("[RuntimeEnv] rawHost :", rawHost)
// // 多层反代时 x-forwarded-host 可能是 "a.com, b.com"
// // host 可能附带端口,须砍掉
// const hostname = rawHost.split(",")[0].split(":")[0].trim()
// console.log("[RuntimeEnv] hostname :", hostname)
// /* ──────────────── 3. 拼最终 URL (端口固定 8000) ──────────────── */
// const supabaseUrl = `${proto}://${hostname}:8000`
// console.log("[RuntimeEnv] supabaseUrl to inject:", supabaseUrl)
// /* ──────────────── 4. 把脚本塞进 HTML ──────────────── */
// useServerInsertedHTML(() => {
// // 这一段在 React 把 HTML flush 给客户端之前执行一次
// console.log("[RuntimeEnv] <script> tag inserted into HTML")
// return (
// <script
// // 行内脚本window.RUNTIME_ENV.SUPABASE_URL = "<url>"
// dangerouslySetInnerHTML={{
// __html: `window.RUNTIME_ENV = { SUPABASE_URL: ${JSON.stringify(
// supabaseUrl,
// )} };`,
// }}
// />
// )
// })
// /* ──────────────── 5. 渲染子节点 ──────────────── */
// return <>{children}</> // Provider 本身不渲染 UI只负责注入脚本
// }
// app/_runtime-env-provider.tsx (务必保持在 app 目录 ➜ Server 组件)
import { headers } from "next/headers"
import { useServerInsertedHTML } from "next/navigation"
import React from "react"
// ------------------- 带全链路调试日志的版本 -------------------
export function RuntimeEnvProvider({ children }: { children: React.ReactNode }) {
/* ──────────────── 1. 解析协议 ──────────────── */
const h = headers() // <-- Node 边界:读取当前请求头
/* 解析请求头 */
const h = headers()
console.log("[RuntimeEnv] Raw headers:", Object.fromEntries(h.entries()))
const proto =
h.get("x-forwarded-proto") ?? // 走 Nginx / 反代时最可靠
(h.get("host")?.includes(":443") ? "https" : "http")// 没有反代时根据端口猜
h.get("x-forwarded-proto") ??
(h.get("host")?.includes(":443") ? "https" : "http")
console.log("[RuntimeEnv] Resolved protocol:", proto)
/* ──────────────── 2. 解析主机名 ──────────────── */
const rawHost = h.get("x-forwarded-host") ?? h.get("host")!
console.log("[RuntimeEnv] rawHost :", rawHost)
// 多层反代时 x-forwarded-host 可能是 "a.com, b.com"
// host 可能附带端口,须砍掉
const hostname = rawHost.split(",")[0].split(":")[0].trim()
console.log("[RuntimeEnv] hostname :", hostname)
/* ──────────────── 3. 拼最终 URL (端口固定 8000) ──────────────── */
const supabaseUrl = `${proto}://${hostname}:8000`
console.log("[RuntimeEnv] supabaseUrl to inject:", supabaseUrl)
/* ──────────────── 4. 把脚本塞进 HTML ──────────────── */
/* 把脚本塞进 HTML这一行如果不打印说明没执行 */
useServerInsertedHTML(() => {
// 这一段在 React 把 HTML flush 给客户端之前执行一次
console.log("[RuntimeEnv] <script> tag inserted into HTML")
return (
<script
// 行内脚本window.RUNTIME_ENV.SUPABASE_URL = "<url>"
id="runtime-env" /* 方便 View-Source 检查 */
dangerouslySetInnerHTML={{
__html: `window.RUNTIME_ENV = { SUPABASE_URL: ${JSON.stringify(
supabaseUrl,
)} };`,
)} }; console.log('[Client] window.RUNTIME_ENV =', window.RUNTIME_ENV);`,
}}
/>
)
})
/* ──────────────── 5. 渲染子节点 ──────────────── */
return <>{children}</> // Provider 本身不渲染 UI只负责注入脚本
return <>{children}</>
}