gongxiangp2/lib/network.ts

133 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 网络管理:智能检测内外网
// 判断是否为内网IP地址
function isInternalIP(hostname: string): boolean {
// 如果是localhost
if (hostname === 'localhost' || hostname === '127.0.0.1') {
return true
}
// 判断是否为内网IP段
// 10.0.0.0 - 10.255.255.255
// 172.16.0.0 - 172.31.255.255
// 192.168.0.0 - 192.168.255.255
const ipv4Regex = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
const match = hostname.match(ipv4Regex)
if (match) {
const [, a, b] = match.map(Number)
// 10.x.x.x
if (a === 10) return true
// 172.16.x.x - 172.31.x.x
if (a === 172 && b >= 16 && b <= 31) return true
// 192.168.x.x
if (a === 192 && b === 168) return true
}
return false
}
function getCurrentHost(): string {
if (typeof window === 'undefined') return ''
return window.location.host
}
function getCurrentHostname(): string {
if (typeof window === 'undefined') return ''
return window.location.hostname
}
export interface NetworkStatus {
isInternal: boolean
host: string
}
let currentNetwork: NetworkStatus | null = null
// 初始化网络检测(优先使用后端API获取准确状态)
export async function initializeNetwork(): Promise<NetworkStatus> {
if (typeof window === 'undefined') {
return { isInternal: false, host: '' }
}
// 如果已经检测过,直接返回缓存结果
if (currentNetwork) {
return currentNetwork
}
const host = getCurrentHost()
const hostname = getCurrentHostname()
// 优先调用后端API获取准确的网络状态(后端可以通过请求头获取真实的客户端IP)
try {
const response = await fetch('/api/network-status', {
cache: 'no-store', // 不缓存,确保获取最新状态
})
if (response.ok) {
const data = await response.json()
if (data.success) {
currentNetwork = {
isInternal: data.isIntranet,
host
}
// 不输出IP和Hostname信息,避免在浏览器控制台暴露内网信息
if (data.isIntranet) {
console.log(`✅ 检测到内网访问`)
} else {
console.log(`🌐 检测到公网访问`)
}
return currentNetwork
}
}
} catch (error) {
console.warn('后端网络检测失败,使用前端判断:', error)
}
// 如果后端API调用失败,回退到前端判断(基于hostname)
const isInternal = isInternalIP(hostname)
currentNetwork = {
isInternal,
host
}
// 不输出hostname信息,避免在浏览器控制台暴露内网信息
if (isInternal) {
console.log(`✅ 检测到内网访问`)
} else {
console.log(`🌐 检测到公网访问`)
}
return currentNetwork
}
// 获取当前网络状态
export function getNetworkStatus(): NetworkStatus {
if (!currentNetwork) {
const host = getCurrentHost()
const hostname = getCurrentHostname()
const isInternal = isInternalIP(hostname)
return { isInternal, host }
}
return currentNetwork
}
// 获取API基础URL
export function getApiBaseUrl(): string {
if (!currentNetwork) {
return '' // 使用相对路径
}
return currentNetwork.isInternal ? `http://${currentNetwork.host}` : ''
}
// 清除缓存(用于刷新网络状态)
export function clearNetworkCache() {
currentNetwork = null
}