Merge pull request #16 from rustfs/dev_endpoint

feat: get config from server config file
This commit is contained in:
cxymds
2025-09-19 14:15:24 +08:00
committed by GitHub
2 changed files with 189 additions and 86 deletions
+84 -27
View File
@@ -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<SiteConfig | null> => {
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)
}
const defaultServerHost = 'http://localhost:9000';
return createDefaultConfig(defaultServerHost);
};
+105 -59
View File
@@ -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<SiteConfig | null> {
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<SiteConfig> {
// 检查缓存
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<boolean> {
const config = await this.loadConfig()
return !!(config?.serverHost && config?.api?.baseURL)
}
}
const config = await this.loadConfig();
return !!(config?.serverHost && config?.api?.baseURL);
},
// 强制从服务器重新加载配置并更新缓存
async reloadConfigFromServer(): Promise<SiteConfig | null> {
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;
}
},
};