From a96449d564061876f942db47e31dc12b4bf0804b Mon Sep 17 00:00:00 2001 From: cxymds Date: Mon, 15 Sep 2025 21:41:39 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=20get=20config=20from=20server=20?= =?UTF-8?q?config=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/config-helpers.ts | 111 ++++++++++++++++++++------- utils/config.ts | 164 +++++++++++++++++++++++++--------------- 2 files changed, 189 insertions(+), 86 deletions(-) diff --git a/utils/config-helpers.ts b/utils/config-helpers.ts index 8fe2b8a..e214216 100644 --- a/utils/config-helpers.ts +++ b/utils/config-helpers.ts @@ -1,5 +1,5 @@ -import type { SiteConfig } from '~/types/config' -import { logger } from './logger' +import type { SiteConfig } from '~/types/config'; +import { logger } from './logger'; /** * 创建默认配置 @@ -8,48 +8,105 @@ export const createDefaultConfig = (serverHost: string): SiteConfig => { return { serverHost, api: { - baseURL: `${serverHost}/rustfs/admin/v3` + baseURL: `${serverHost}/rustfs/admin/v3`, }, s3: { endpoint: serverHost, region: 'us-east-1', accessKeyId: '', - secretAccessKey: '' - } - } -} + secretAccessKey: '', + }, + }; +}; /** * 从localStorage获取保存的主机配置 */ export const getStoredHostConfig = (): SiteConfig | null => { - if (typeof window === 'undefined') return null - - const savedHost = localStorage.getItem('rustfs-server-host') - if (!savedHost) return null + if (typeof window === 'undefined') return null; + + const savedHost = localStorage.getItem('rustfs-server-host'); + if (!savedHost) return null; try { - const url = new URL(savedHost) - const serverHost = `${url.protocol}//${url.host}` - return createDefaultConfig(serverHost) + const url = new URL(savedHost); + const serverHost = `${url.protocol}//${url.host}`; + return createDefaultConfig(serverHost); } catch (error) { - logger.warn('Invalid saved host configuration:', error) - return null + logger.warn('Invalid saved host configuration:', error); + return null; } -} +}; /** * 获取当前浏览器主机配置 */ export const getCurrentBrowserConfig = (): SiteConfig | null => { - if (typeof window === 'undefined') return null + if (typeof window === 'undefined') return null; - const currentHost = window.location.host - const protocol = window.location.protocol.replace(':', '') - const serverHost = `${protocol}://${currentHost}` - - return createDefaultConfig(serverHost) -} + const currentHost = window.location.host; + const protocol = window.location.protocol.replace(':', ''); + const serverHost = `${protocol}://${currentHost}`; + + return createDefaultConfig(serverHost); +}; + +/** + * 从当前浏览器host获取配置 + */ +export const fetchConfigFromServer = async (): Promise => { + if (typeof window === 'undefined') return null; + + try { + const currentHost = window.location.hostname; + const currentPort = window.location.port; + const protocol = window.location.protocol; + const serverHost = `${protocol}//${currentHost}${currentPort ? `:${currentPort}` : ':9000'}`; + const configUrl = `${serverHost}/config.json`; + + const response = await fetch(configUrl, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + // 设置5秒超时 + signal: AbortSignal.timeout(5000), + }); + + if (!response.ok) { + logger.warn(`Failed to fetch config from ${configUrl}: ${response.status} ${response.statusText}`); + return null; + } + + const serverConfig = await response.json(); + + // 验证配置格式 - 检查是否为对象 + if (typeof serverConfig !== 'object' || serverConfig === null) { + // logger.warn('Invalid server config: not a valid object'); + return null; + } + + // 直接使用返回的配置数据 + const config: SiteConfig = { + serverHost: serverHost, + api: { + baseURL: serverConfig.api?.baseURL || `${serverHost}/rustfs/admin/v3`, + }, + s3: { + endpoint: serverConfig.s3?.endpoint || serverHost, + region: serverConfig.s3?.region || 'us-east-1', + accessKeyId: serverConfig.s3?.accessKeyId || '', + secretAccessKey: serverConfig.s3?.secretAccessKey || '', + }, + }; + + logger.info(`Successfully loaded config from server: ${configUrl}`); + return config; + } catch (error) { + logger.warn(`Error fetching config from server: ${error instanceof Error ? error.message : 'Unknown error'}`); + return null; + } +}; /** * 获取服务端默认配置 @@ -57,6 +114,6 @@ export const getCurrentBrowserConfig = (): SiteConfig | null => { export const getServerDefaultConfig = (): SiteConfig => { // 注意:这里按照用户要求,服务端也应该尽量使用当前host // 但由于服务端限制,只能使用localhost作为fallback - const defaultServerHost = 'http://localhost:9000' - return createDefaultConfig(defaultServerHost) -} \ No newline at end of file + const defaultServerHost = 'http://localhost:9000'; + return createDefaultConfig(defaultServerHost); +}; diff --git a/utils/config.ts b/utils/config.ts index 0d17521..e8bba2a 100644 --- a/utils/config.ts +++ b/utils/config.ts @@ -1,119 +1,165 @@ -import type { SiteConfig } from '~/types/config' -import { handleConfigError } from './error-handler' -import { logger } from './logger' -import { - createDefaultConfig, - getStoredHostConfig, - getCurrentBrowserConfig, - getServerDefaultConfig -} from './config-helpers' +import type { SiteConfig } from '~/types/config'; +import { handleConfigError } from './error-handler'; +import { logger } from './logger'; +import { + createDefaultConfig, + getStoredHostConfig, + getCurrentBrowserConfig, + getServerDefaultConfig, + fetchConfigFromServer, +} from './config-helpers'; export interface RustFSConfig { - serverHost: string + serverHost: string; api: { - baseURL: string - } + baseURL: string; + }; s3: { - endpoint: string - region: string - } + endpoint: string; + region: string; + }; } // 添加配置缓存 -let configCache: SiteConfig | null = null -let configCacheTime = 0 -const CACHE_DURATION = 60000 // 1分钟缓存 +let configCache: SiteConfig | null = null; +let configCacheTime = 0; +const CACHE_DURATION = 60000; // 1分钟缓存 export const configManager = { // 获取当前host配置 getCurrentHostConfig(): SiteConfig { // 优先使用localStorage中保存的配置 - const storedConfig = getStoredHostConfig() + const storedConfig = getStoredHostConfig(); if (storedConfig) { - return storedConfig + return storedConfig; } // 使用当前浏览器地址 - const browserConfig = getCurrentBrowserConfig() + const browserConfig = getCurrentBrowserConfig(); if (browserConfig) { - return browserConfig + return browserConfig; } // 服务端fallback - return getServerDefaultConfig() + return getServerDefaultConfig(); }, // 从 nuxt runtimeconfig 读取配置 loadRuntimeConfig(): SiteConfig | null { try { - const runtimeConfig = useRuntimeConfig() - + const runtimeConfig = useRuntimeConfig(); + // 优先使用 serverHost,然后是 API_BASE_URL - const serverHost = runtimeConfig.public?.serverHost || - runtimeConfig.public?.api?.baseURL?.replace(/\/rustfs\/admin\/v3$/, '') - + const serverHost = + runtimeConfig.public?.serverHost || runtimeConfig.public?.api?.baseURL?.replace(/\/rustfs\/admin\/v3$/, ''); + if (serverHost) { return { serverHost, api: { - baseURL: runtimeConfig.public.api?.baseURL || `${serverHost}/rustfs/admin/v3` + baseURL: runtimeConfig.public.api?.baseURL || `${serverHost}/rustfs/admin/v3`, }, s3: { endpoint: runtimeConfig.public.s3?.endpoint || serverHost, region: runtimeConfig.public.s3?.region || 'us-east-1', accessKeyId: '', - secretAccessKey: '' + secretAccessKey: '', }, - session: runtimeConfig.public.session - } + session: runtimeConfig.public.session, + }; } } catch (error) { - const configError = handleConfigError(error, 'runtime config loading') - logger.warn('Failed to load runtime config:', configError.message) + const configError = handleConfigError(error, 'runtime config loading'); + logger.warn('Failed to load runtime config:', configError.message); } - return null + return null; }, - // 加载配置:优先使用localStorage,然后是当前host,最后是runtimeconfig + // 从服务器获取配置 (当前浏览器host:9001/config.json) + async loadConfigFromServer(): Promise { + try { + return await fetchConfigFromServer(); + } catch (error) { + const configError = handleConfigError(error, 'server config loading'); + logger.warn('Failed to load config from server:', configError.message); + return null; + } + }, + + // 加载配置:优先使用localStorage,然后尝试服务器配置,当前host,最后是runtimeconfig async loadConfig(): Promise { // 检查缓存 - const now = Date.now() - if (configCache && (now - configCacheTime) < CACHE_DURATION) { - return configCache + const now = Date.now(); + if (configCache && now - configCacheTime < CACHE_DURATION) { + return configCache; } - let config: SiteConfig + let config: SiteConfig; - // 优先使用当前host配置(包括localStorage检查) - const currentHostConfig = this.getCurrentHostConfig() - if (currentHostConfig) { - config = currentHostConfig + // 1. 优先使用localStorage中保存的配置 + const storedConfig = getStoredHostConfig(); + if (storedConfig) { + config = storedConfig; } else { - // 如果没有当前host配置,使用 runtimeconfig - const runtimeConfig = this.loadRuntimeConfig() - if (runtimeConfig) { - config = runtimeConfig + // 2. 尝试从服务器获取配置 (当前浏览器host:9001/config.json) + const serverConfig = await this.loadConfigFromServer(); + if (serverConfig) { + config = serverConfig; } else { - // 最后使用浏览器当前地址或服务端默认值 - config = getCurrentBrowserConfig() || getServerDefaultConfig() + // 3. 使用当前浏览器地址 + const browserConfig = getCurrentBrowserConfig(); + if (browserConfig) { + config = browserConfig; + } else { + // 4. 使用 runtimeconfig + const runtimeConfig = this.loadRuntimeConfig(); + if (runtimeConfig) { + config = runtimeConfig; + } else { + // 5. 最后使用服务端默认值 + config = getServerDefaultConfig(); + } + } } } // 缓存配置 - configCache = config - configCacheTime = now - return config + configCache = config; + configCacheTime = now; + return config; }, // 清除缓存 clearCache() { - configCache = null - configCacheTime = 0 + configCache = null; + configCacheTime = 0; }, // 检查是否有有效配置 async hasValidConfig(): Promise { - const config = await this.loadConfig() - return !!(config?.serverHost && config?.api?.baseURL) - } -} \ No newline at end of file + const config = await this.loadConfig(); + return !!(config?.serverHost && config?.api?.baseURL); + }, + + // 强制从服务器重新加载配置并更新缓存 + async reloadConfigFromServer(): Promise { + try { + // 清除缓存 + this.clearCache(); + + // 从服务器加载配置 + const config = await this.loadConfigFromServer(); + if (config) { + // 更新缓存 + configCache = config; + configCacheTime = Date.now(); + logger.info('Configuration reloaded from server successfully'); + } + return config; + } catch (error) { + const configError = handleConfigError(error, 'reloading config from server'); + logger.error('Failed to reload config from server:', configError.message); + return null; + } + }, +};