完整工具類
using System;
using System.Text.RegularExpressions;
using System.Web;
public static class ClientInfoHelper
{
/// 取得作業系統
public static string GetOS()
{
string ua = HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"] ?? "";
if (ua.Contains("Windows NT 10.0")) return "Windows 10/11";
if (ua.Contains("Windows NT 6.3")) return "Windows 8.1";
if (ua.Contains("Windows NT 6.2")) return "Windows 8";
if (ua.Contains("Windows NT 6.1")) return "Windows 7";
if (ua.Contains("Windows NT 6.0")) return "Windows Vista";
if (ua.Contains("Windows NT 5.2")) return "Windows Server 2003/XP x64";
if (ua.Contains("Windows NT 5.1")) return "Windows XP";
if (ua.Contains("Windows NT 5.0")) return "Windows 2000";
if (ua.Contains("Mac OS X")) return "macOS";
if (ua.Contains("iPhone") || ua.Contains("iPad")) return "iOS";
if (ua.Contains("Android")) return "Android";
if (ua.Contains("Linux")) return "Linux";
if (ua.Contains("Unix")) return "Unix";
return "Unknown";
}
/// 取得瀏覽器名稱與版本
public static string GetBrowser()
{
string ua = HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"] ?? "";
// Edge (Chromium)
var m = Regex.Match(ua, @"Edg/(\d+\.\d+\.\d+\.\d+)");
if (m.Success) return $"Edge {m.Groups[1].Value}";
// Chrome
m = Regex.Match(ua, @"Chrome/(\d+\.\d+\.\d+\.\d+)");
if (m.Success && !ua.Contains("Edg")) return $"Chrome {m.Groups[1].Value}";
// Firefox
m = Regex.Match(ua, @"Firefox/(\d+\.\d+)");
if (m.Success) return $"Firefox {m.Groups[1].Value}";
// Safari
m = Regex.Match(ua, @"Version/(\d+\.\d+).*Safari");
if (m.Success && !ua.Contains("Chrome")) return $"Safari {m.Groups[1].Value}";
// IE 11
if (ua.Contains("Trident/7.0") || ua.Contains("rv:11.0")) return "IE 11";
// IE 10-
m = Regex.Match(ua, @"MSIE (\d+\.\d+)");
if (m.Success) return $"IE {m.Groups[1].Value}";
return "Unknown";
}
/// 取得客戶端 IP(支援代理/負載平衡)
public static string GetClientIP()
{
var request = HttpContext.Current.Request;
string ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ip))
{
// 可能包含多個 IP,取第一個非私有 IP
foreach (var part in ip.Split(','))
{
var trimmed = part.Trim();
if (IsPublicIP(trimmed)) return trimmed;
}
return ip.Split(',')[0].Trim();
}
ip = request.ServerVariables["HTTP_X_REAL_IP"];
if (!string.IsNullOrEmpty(ip)) return ip;
return request.ServerVariables["REMOTE_ADDR"] ?? "";
}
private static bool IsPublicIP(string ip)
{
if (!System.Net.IPAddress.TryParse(ip, out var addr)) return false;
var bytes = addr.GetAddressBytes();
// 簡易私有網段判斷
if (bytes[0] == 10) return false;
if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31) return false;
if (bytes[0] == 192 && bytes[1] == 168) return false;
if (bytes[0] == 127) return false;
return true;
}
}
使用範例
protected void Page_Load(object sender, EventArgs e)
{
lblInfo.Text = $"OS: {ClientInfoHelper.GetOS()}
" +
$"Browser: {ClientInfoHelper.GetBrowser()}
" +
$"IP: {ClientInfoHelper.GetClientIP()}";
}
進階建議
- User-Agent 解析庫: 使用
UAParser (NuGet) 獲得更準確、可維護的解析,支援數千種裝置/瀏覽器規則自動更新。
- Client Hints: 現代瀏覽器支援
Sec-CH-UA、Sec-CH-UA-Platform 等標準標頭,比 UA 字串更結構化。
- 隱私考量: GDPR/個資法要求告知蒐集目的、最小化原則,IP 屬個資需謹慎處理。
- 快取: 同一 Session 內多次呼叫可快取結果,減少解析開銷。