C#获取FritzBox路由器首页时程序无异常终止问题求助
问题:C#请求FritzBox首页时程序无预警终止
使用C#获取FritzBox路由器首页内容时,携带已获取的SID请求页面,程序会突然终止,既不触发断点也不抛出异常。已尝试修改HttpClient请求头模拟浏览器行为,但问题仍未解决。
相关代码
private static async Task<string> GetSessionId() { using (var client = new HttpClient() { BaseAddress = new Uri(FritzBoxUrl)}) { var response = await client.GetStringAsync("/login_sid.lua"); var xml = XDocument.Parse(response); var sid = xml.Root.Element("SID").Value; if (sid != "0000000000000000") { return sid; } var challenge = xml.Root.Element("Challenge").Value; fritzUserName = xml.Root.Element("Users")?.Element("User").Value; var responseHash = CalculateMD5(challenge + "-" + Password); var content = new StringContent($"response={challenge}-{responseHash}&username={fritzUserName}", Encoding.UTF8, "application/x-www-form-urlencoded"); var loginResponse = await client.PostAsync("/login_sid.lua", content); var loginResponseContent = await loginResponse.Content.ReadAsStringAsync(); var loginXml = XDocument.Parse(loginResponseContent); var loginSid = loginXml.Root.Element("SID").Value; if (loginSid == "0000000000000000") { throw new Exception(); } return loginSid; } } private static async Task<string> GetOverViewPageHtml(string sid) { try { HttpClient client = new HttpClient() { BaseAddress = new Uri(FritzBoxUrl) }; var firstDataContent = new StringContent( $"xhr=1&sid={sid}&lang=de&page=overview&xhrId=all&useajax=1&no_sidrenew=", Encoding.UTF8, "application/x-www-form-urlencoded"); var firstDataResponse = await client.PostAsync($"{FritzBoxUrl}/data.lua", firstDataContent); var firstDataResponseContent = await firstDataResponse.Content.ReadAsStringAsync(); Console.WriteLine("First data response:"); Console.WriteLine(firstDataResponseContent); var postData = $"xhr=1&sid={sid}&lang=de&page=overview&xhrId=all&useajax=1&no_sidrenew="; var content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded"); Console.WriteLine(content); var response = await client.PostAsync("/data.lua", content); if (response.IsSuccessStatusCode) return await response.Content.ReadAsStringAsync(); throw new Exception(""); } catch (Exception ex) { //<-- this dont get executed! Console.WriteLine(ex); //return null; return string.Empty; } }
BurpSuite捕获的正常请求流程
第一步:登录请求
POST /index.lua HTTP/1.1 Host: fritz.box Content-Length: 148 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://fritz.box Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://fritz.box/ Accept-Encoding: gzip, deflate, br Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7 Connection: keep-alive response=someSecret&lp=&loginView=simple&username=fritz6305
第二步:初始化首页数据请求
POST /data.lua HTTP/1.1 Host: fritz.box Content-Length: 72 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36 Content-Type: application/x-www-form-urlencoded Accept: */* Origin: http://fritz.box Referer: http://fritz.box/ Accept-Encoding: gzip, deflate, br Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7 Connection: keep-alive xhr=1&sid=ed6ed8a316e0c8be&lang=de&page=overview&xhrId=first&noMenuRef=1
第三步:获取完整首页数据请求
POST /data.lua HTTP/1.1 Host: fritz.box Content-Length: 81 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36 Content-Type: application/x-www-form-urlencoded Accept: */* Origin: http://fritz.box Referer: http://fritz.box/ Accept-Encoding: gzip, deflate, br Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7 Connection: keep-alive xhr=1&sid=ed6ed8a316e0c8be&lang=de&page=overview&xhrId=all&useajax=1&no_sidrenew=
问题分析与解决方案
核心问题点
- 请求流程不匹配:代码直接请求
xhrId=all的data.lua,但浏览器实际先请求index.lua完成登录会话初始化,再请求xhrId=first的data.lua,最后才是xhrId=all的请求。 - HttpClient使用错误:第一个
PostAsync拼接了完整URL{FritzBoxUrl}/data.lua,但已设置BaseAddress,应仅使用路径/data.lua,否则会导致URL拼接错误;同时频繁创建HttpClient实例,可能引发连接池问题。 - 缺少关键请求头:虽然尝试模拟浏览器头,但可能未完全覆盖(如
Cache-Control、Upgrade-Insecure-Requests等),FritzBox可能会校验请求头合法性。 - 未处理全局异常:程序终止可能是因为抛出了未被
try/catch捕获的异常(如Task取消、线程异常),需要添加全局异常捕获。 - 异步调用问题:调用
GetOverViewPageHtml时若未使用await,会导致程序提前退出。
修复步骤
- 复用HttpClient实例:创建全局HttpClient实例,避免每次请求都新建。
- 严格遵循浏览器请求流程:先发送
index.lua的登录请求,再依次发送xhrId=first和xhrId=all的data.lua请求。 - 完整模拟浏览器请求头:给HttpClient添加所有浏览器发送的请求头。
- 添加全局异常捕获:在程序入口处注册
AppDomain.CurrentDomain.UnhandledException事件,捕获未处理异常。 - 确保异步调用正确:调用
GetOverViewPageHtml时必须使用await。
修改后的示例代码片段
// 全局HttpClient实例 private static readonly HttpClient _httpClient = new HttpClient(); private static async Task<string> GetOverViewPageHtml(string sid) { try { _httpClient.BaseAddress = new Uri(FritzBoxUrl); // 添加浏览器请求头 _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36"); _httpClient.DefaultRequestHeaders.Add("Origin", FritzBoxUrl); _httpClient.DefaultRequestHeaders.Add("Referer", FritzBoxUrl + "/"); _httpClient.DefaultRequestHeaders.Accept.ParseAdd("*/*"); _httpClient.DefaultRequestHeaders.AcceptEncoding.ParseAdd("gzip, deflate, br"); _httpClient.DefaultRequestHeaders.AcceptLanguage.ParseAdd("de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"); // 第一步:发送index.lua登录请求(补充对应的response参数,可从GetSessionId流程中获取) var loginContent = new StringContent($"response=yourChallengeHash&lp=&loginView=simple&username={fritzUserName}", Encoding.UTF8, "application/x-www-form-urlencoded"); var loginResponse = await _httpClient.PostAsync("/index.lua", loginContent); loginResponse.EnsureSuccessStatusCode(); // 第二步:发送xhrId=first的data.lua请求 var firstDataContent = new StringContent( $"xhr=1&sid={sid}&lang=de&page=overview&xhrId=first&noMenuRef=1", Encoding.UTF8, "application/x-www-form-urlencoded"); var firstDataResponse = await _httpClient.PostAsync("/data.lua", firstDataContent); var firstDataResponseContent = await firstDataResponse.Content.ReadAsStringAsync(); Console.WriteLine("First data response:"); Console.WriteLine(firstDataResponseContent); // 第三步:发送xhrId=all的data.lua请求 var postData = $"xhr=1&sid={sid}&lang=de&page=overview&xhrId=all&useajax=1&no_sidrenew="; var content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded"); var response = await _httpClient.PostAsync("/data.lua", content); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } catch (Exception ex) { Console.WriteLine($"Exception caught: {ex.Message}\n{ex.StackTrace}"); return string.Empty; } } // 程序入口添加全局异常捕获 static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += (sender, e) => { Console.WriteLine($"Unhandled exception: {e.ExceptionObject}"); }; // 异步调用需用GetAwaiter().GetResult()或await var result = GetOverViewPageHtml("yourSid").GetAwaiter().GetResult(); }
内容的提问来源于stack exchange,提问作者SoldatXwing
相关产品推荐
相关产品推荐

