import { NextRequest, NextResponse } from 'next/server' export const dynamic = 'force-dynamic' /** * 判断IP是否为内网地址 */ function isIntranetIP(ip: string): boolean { if (!ip) return false // 处理可能存在的端口号 const cleanIP = ip.split(':')[0] // localhost if (cleanIP === '127.0.0.1' || cleanIP === 'localhost' || cleanIP === '::1') { return true } // IPv4 内网IP段判断 const ipv4Regex = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ const match = cleanIP.match(ipv4Regex) if (match) { const [, a, b, c, d] = match.map(Number) // 验证IP有效性 if (a > 255 || b > 255 || c > 255 || d > 255) { return false } // 10.0.0.0 - 10.255.255.255 (Class A) if (a === 10) return true // 172.16.0.0 - 172.31.255.255 (Class B) if (a === 172 && b >= 16 && b <= 31) return true // 192.168.0.0 - 192.168.255.255 (Class C) if (a === 192 && b === 168) return true // 169.254.0.0 - 169.254.255.255 (Link-local) if (a === 169 && b === 254) return true } return false } /** * 获取客户端真实IP地址 */ function getClientIP(request: NextRequest): string { // 优先级:x-real-ip > x-forwarded-for > connection const xRealIP = request.headers.get('x-real-ip') if (xRealIP) return xRealIP const xForwardedFor = request.headers.get('x-forwarded-for') if (xForwardedFor) { // x-forwarded-for 可能包含多个IP,取第一个(客户端真实IP) return xForwardedFor.split(',')[0].trim() } const cfConnectingIP = request.headers.get('cf-connecting-ip') // Cloudflare if (cfConnectingIP) return cfConnectingIP const trueClientIP = request.headers.get('true-client-ip') // Akamai if (trueClientIP) return trueClientIP // 如果都没有,返回默认值 return 'unknown' } /** * GET /api/network-status * 返回用户的网络环境状态 */ export async function GET(request: NextRequest) { try { const clientIP = getClientIP(request) const isIntranet = isIntranetIP(clientIP) // 获取当前访问的域名 const hostname = request.headers.get('host') || '' const publicDomains = (process.env.PUBLIC_DOMAINS || '').split(',').map(s => s.trim()).filter(Boolean) const isPublicDomain = publicDomains.length > 0 ? publicDomains.includes(hostname) : false console.log(`[Network Status] IP: ${clientIP}, isIntranet: ${isIntranet}, hostname: ${hostname}`) return NextResponse.json({ success: true, isIntranet, isPublicDomain, // 不返回完整IP地址(隐私保护) ipMasked: clientIP.split('.').slice(0, 2).join('.') + '.xxx.xxx', message: isIntranet ? '检测到内网访问' : '检测到公网访问', intranetUrl: isIntranet && isPublicDomain ? (process.env.NEXT_PUBLIC_INTRANET_URL || '') : null }) } catch (error) { console.error('[Network Status] Error:', error) return NextResponse.json({ success: false, error: '网络状态检测失败' }, { status: 500 }) } }