const LOCAL_KEY = "SUPABASE_URL"; const MAX_RETRIES = 5; const RETRY_DELAY = 1000; export async function getRuntimeEnv(key: string): Promise { if (typeof window !== "undefined") { let retries = 0; while (retries < MAX_RETRIES) { // 1. 尝试 window.RUNTIME_ENV 提取IP const val = window.RUNTIME_ENV?.[key]; const ip = extractIp(val); if (ip) { if (key === "SUPABASE_URL") { window.localStorage.setItem(LOCAL_KEY, val!); // 这里存原始值 console.log(`[env] [${key}] 命中 window.RUNTIME_ENV: ${val},提取IP: ${ip},已同步到localStorage`); } else { console.log(`[env] [${key}] 命中 window.RUNTIME_ENV: ${val},提取IP: ${ip}`); } return ip; } else if (val) { console.warn(`[env] [${key}] window.RUNTIME_ENV 有值但无法提取合法IP: ${val}`); } retries++; // 2. 第3次开始查localStorage兜底 if (retries >= 2) { const cached = window.localStorage.getItem(LOCAL_KEY); const cachedIp = extractIp(cached); if (cachedIp && key === "SUPABASE_URL") { console.warn(`[env] [${key}] 第${retries}次重试后window.RUNTIME_ENV还没拿到合法IP,localStorage兜底: ${cached},提取IP: ${cachedIp}`); return cachedIp; } } if (retries < MAX_RETRIES) { console.log(`[env] [${key}] window.RUNTIME_ENV 暂无合法IP,第${retries}次重试,${RETRY_DELAY}ms后再试...`); await new Promise(res => setTimeout(res, RETRY_DELAY)); } } // 3. 所有重试和localStorage都失败 console.error(`[env] [${key}] window.RUNTIME_ENV、localStorage都无合法IP,返回undefined`); return undefined; } else { // 服务端 const val = process.env[key]; const ip = extractIp(val); console.log(`[env][server] 直接读取 process.env[${key}]:`, val, "提取IP:", ip); return ip; } } // --------- 需要配合的工具函数 --------- function isValidIp(ip: string | undefined): boolean { if (!ip) return false; const reg = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/; return reg.test(ip); } function extractIp(str: string | undefined): string | undefined { if (!str) return undefined; if (isValidIp(str)) return str; try { const url = new URL(str); if (isValidIp(url.hostname)) return url.hostname; } catch {} const match = str.match(/(\d{1,3}(?:\.\d{1,3}){3})/); if (match && isValidIp(match[1])) return match[1]; return undefined; }