From d49a5a3bea311baed65f1c71888df1b97f69bfd9 Mon Sep 17 00:00:00 2001 From: hailin Date: Sun, 15 Jun 2025 12:42:43 +0800 Subject: [PATCH] . --- .../app/[locale]/details/[slug]/page.tsx | 24 +++++++++- apps/blogai/app/[locale]/qa/[slug]/page.tsx | 24 +++++++++- apps/blogai/components/chat-model.tsx | 44 ------------------- apps/blogai/components/header.tsx | 25 ++++++++++- apps/blogai/lib/http/axios_config.ts | 16 ++++++- 5 files changed, 85 insertions(+), 48 deletions(-) diff --git a/apps/blogai/app/[locale]/details/[slug]/page.tsx b/apps/blogai/app/[locale]/details/[slug]/page.tsx index cbe7856..3afd730 100644 --- a/apps/blogai/app/[locale]/details/[slug]/page.tsx +++ b/apps/blogai/app/[locale]/details/[slug]/page.tsx @@ -17,6 +17,7 @@ import { baseTitle, baseURL, keywordsRoot } from "@/lib/metadata"; import { useTranslation } from "react-i18next"; import { DetailPageHeader } from '@/components/header' +import { getRuntimeEnv } from "@/lib/ipconfig"; export const runtime = "nodejs"; @@ -25,6 +26,26 @@ type Props = { searchParams: { [key: string]: string | string[] | undefined }; }; +// 推荐用法,async 获取 +export async function getBaseUrl() { + const ip = await getRuntimeEnv("SUPABASE_URL"); + if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 baseUrl"); + + // 判断协议 + let protocol = "http"; + if ( + typeof window !== "undefined" && + window.location && + window.location.protocol === "https:" + ) { + protocol = "https"; + ip = window.location.hostname; // ✅ HTTPS 场景下安全替换 IP 为域名 + } + + // 拼接 + return `${protocol}://${ip}`; +} + export async function generateMetadata({ params }: Props): Promise { const { serialized, frontmatter, headings } = await getPostContent(params.locale, params.slug); @@ -35,7 +56,8 @@ export async function generateMetadata({ params }: Props): Promise { return notFound(); } - const baseUrl = process.env.VERCEL_URL ? process.env.VERCEL_URL : baseURL; + //const baseUrl = process.env.VERCEL_URL ? process.env.VERCEL_URL : baseURL; + const baseUrl = await getBaseUrl(); const ogUrl = new URL("/og/blog", baseUrl); const author = authors[frontmatter.author]; ogUrl.searchParams.set("title", frontmatter.title ?? ""); diff --git a/apps/blogai/app/[locale]/qa/[slug]/page.tsx b/apps/blogai/app/[locale]/qa/[slug]/page.tsx index 2627b91..d171ee5 100644 --- a/apps/blogai/app/[locale]/qa/[slug]/page.tsx +++ b/apps/blogai/app/[locale]/qa/[slug]/page.tsx @@ -17,6 +17,27 @@ import { baseTitle, baseURL, keywordsRoot } from "@/lib/metadata"; export const runtime = "nodejs"; +// 推荐用法,async 获取 +export async function getBaseUrl() { + const ip = await getRuntimeEnv("SUPABASE_URL"); + if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 baseUrl"); + + // 判断协议 + let protocol = "http"; + if ( + typeof window !== "undefined" && + window.location && + window.location.protocol === "https:" + ) { + protocol = "https"; + // ✅ 只在 HTTPS 客户端场景下用 hostname 替换 IP + ip = window.location.hostname; + } + + // 拼接 + return `${protocol}://${ip}`; +} + type Props = { params: { locale: string, slug: string; title: string; description: string; authorName: string }; searchParams: { [key: string]: string | string[] | undefined }; @@ -32,7 +53,8 @@ export async function generateMetadata({ params }: Props): Promise { return notFound(); } - const baseUrl = process.env.VERCEL_URL ? process.env.VERCEL_URL : baseURL; + //const baseUrl = process.env.VERCEL_URL ? process.env.VERCEL_URL : baseURL; + const baseUrl = await getBaseUrl(); const ogUrl = new URL("/og/blog", baseUrl); const author = authors[frontmatter.author]; ogUrl.searchParams.set("title", frontmatter.title ?? ""); diff --git a/apps/blogai/components/chat-model.tsx b/apps/blogai/components/chat-model.tsx index d317ba8..34bc168 100644 --- a/apps/blogai/components/chat-model.tsx +++ b/apps/blogai/components/chat-model.tsx @@ -277,50 +277,6 @@ export function ChatModel({ } } - - // const isSocket = true - // const { messages, append, reload, stop, isLoading, input, setInput } = - // useChat({ - // experimental_onFunctionCall: functionCallHandler, - // initialMessages, - // id, - // body: { - // id - // }, - // onResponse(response) { - // setIsGenerating(true) - // if (!isChatPage) { - // router.prefetch(`${i18n.language}/chat/${id}`, { - // kind: PrefetchKind.FULL - // }) - // } - // if (response.status === 401) { - // toast.error(response.statusText) - // } - // }, - // onFinish() { - // setIsGenerating(false) - // if (!isChatPage) { - // history.pushState({}, '', `${i18n.language}/chat/${id}`) - // history.go(1) - // } - // } - // }) - - // const optins = !!q ? { - // // initialInput: `{ - // // "method": "REQUEST", - // // "params": - // // [ - // // "@account", - // // "@balance" - // // ], - // // "id": 12 - // // }` - // initialInput: q - // } : {} - // const { messages, append, isLoading, input, setInput, } = useISDK('ws://116.213.39.234:8083/ws', optins); - const { messages, append, setMessages, reload, stop, isLoading, isSocket, input, setInput } = useISDK({ api: `${process.env.NEXT_PUBLIC_CLIENT_BASE_WS}`, diff --git a/apps/blogai/components/header.tsx b/apps/blogai/components/header.tsx index 7a9940c..8b1ac20 100644 --- a/apps/blogai/components/header.tsx +++ b/apps/blogai/components/header.tsx @@ -43,6 +43,7 @@ import { Trash2 } from "lucide-react"; import { useEffect } from "react"; +import { getRuntimeEnv } from "@/lib/ipconfig"; import { BadgeInfo, @@ -116,6 +117,26 @@ export function Header() { ) } +export async function getWsBase() { + const ip = await getRuntimeEnv("SUPABASE_URL"); + if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 wsBase"); + + // 判断协议 + let wsProtocol = "ws"; + if ( + typeof window !== "undefined" && + window.location && + window.location.protocol === "https:" + ) { + wsProtocol = "wss"; + // ✅ HTTPS + 浏览器环境下用 hostname 避免 TLS 报错 + ip = window.location.hostname; + } + + // 拼接最终 ws 地址 + return `${wsProtocol}://${ip}/api/v1/deploy/ws`; +} + export function DetailPageHeader({ data }: { data: any }) { const [loading, setLoading] = useState(false); const [statusText, setStatusText] = useState(data?.statusText || "加载中..."); @@ -133,7 +154,9 @@ export function DetailPageHeader({ data }: { data: any }) { const initWebSocket = (userName: string, id: number) => { if (socketRef.current) socketRef.current.close(); - const wsBase = process.env.NEXT_PUBLIC_CLIENT_BASE_WS; + + //const wsBase = process.env.NEXT_PUBLIC_CLIENT_BASE_WS; + const wsBase = await getWsBase(); const socket = new WebSocket(`${wsBase}/status/${userName}/${id}`); socketRef.current = socket; diff --git a/apps/blogai/lib/http/axios_config.ts b/apps/blogai/lib/http/axios_config.ts index 414c10b..7c6c916 100644 --- a/apps/blogai/lib/http/axios_config.ts +++ b/apps/blogai/lib/http/axios_config.ts @@ -36,8 +36,22 @@ import { getRuntimeEnv } from "@/lib/ipconfig"; export async function getAxiosConfig() { const ip = await getRuntimeEnv("SUPABASE_URL"); // 直接用你 lib/ipconfig 里的方法 if (!ip) throw new Error("SUPABASE_URL 获取失败,无法构建 axios 配置"); + + let protocol = "http"; + let port = 80; + + if (typeof window !== "undefined" && window.location && window.location.protocol) { + protocol = window.location.protocol.replace(":", ""); + port = protocol === "https" ? 443 : 80; + + // ✅ HTTPS + 浏览器时,替换 IP,避免 TLS/CORS 报错 + if (protocol === "https") { + ip = window.location.hostname; + } + } + return { - baseURL: `http://${ip}:80`, // 端口如需动态可再加参数 + baseURL: `${protocol}://${ip}:${port}`, // 端口如需动态可再加参数 method: 'post', timeout: 60 * 1000, headers: { 'Content-Type': 'application/json; charset=UTF-8' },