71 lines
2.6 KiB
TypeScript
71 lines
2.6 KiB
TypeScript
const LOCAL_KEY = "SUPABASE_URL";
|
||
const MAX_RETRIES = 5;
|
||
const RETRY_DELAY = 1000;
|
||
|
||
export async function getRuntimeEnv(key: string): Promise<string | undefined> {
|
||
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;
|
||
}
|