C# HttpClient检测重定向问题:301捕获失败及响应URI获取方案咨询
问题原因说明
你拿到200状态码的核心原因是HttpClient默认开启了自动重定向跟随逻辑,会自动完成所有重定向跳转后才返回最终页面的响应,所以你看不到中间过程的3xx状态码。
你提到的HttpResponseMessage没有响应URI属于误解,该类提供了RequestMessage属性,其下的RequestUri就是最终响应对应的实际请求地址,直接对比初始请求地址和该地址是否一致,即可判断是否发生过重定向。
实现方案
方案1:开启自动重定向,直接对比初始URI和最终URI
适合只需要判断是否发生重定向、不需要获取重定向链路的场景:
// 全局仅初始化一次单例HttpClient即可,避免端口耗尽 private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = true, // 该值为默认值,可省略 MaxAutomaticRedirections = 10 // 限制最大重定向次数,避免死循环 }); // 调用逻辑 Uri originalUri = new Uri("https://grnh.se/8dc368b82us?s=LinkedIn&source=LinkedIn"); HttpResponseMessage response = await _httpClient.GetAsync(originalUri, HttpCompletionOption.ResponseHeadersRead); Uri finalUri = response.RequestMessage.RequestUri; if (originalUri != finalUri) { // 发生过重定向 }
使用HttpCompletionOption.ResponseHeadersRead参数可以让请求仅读取响应头就返回,不需要下载完整响应体,大幅提升批量扫描的效率。
方案2:关闭自动重定向,自行捕获3xx状态码
适合需要获取重定向次数、重定向链路的场景:
// 全局仅初始化一次 private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false }); // 调用逻辑 Uri currentUri = new Uri("https://grnh.se/8dc368b82us?s=LinkedIn&source=LinkedIn"); List<Uri> redirectChain = new List<Uri> { currentUri }; const int MAX_REDIRECT_COUNT = 10; while (redirectChain.Count <= MAX_REDIRECT_COUNT) { using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, currentUri); using HttpResponseMessage response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); int statusCode = (int)response.StatusCode; // 判断是否为重定向状态码 if (statusCode >= 300 && statusCode < 400 && response.Headers.Location != null) { Uri redirectUri = response.Headers.Location; // 处理相对路径的重定向地址 if (!redirectUri.IsAbsoluteUri) { redirectUri = new Uri(currentUri, redirectUri); } redirectChain.Add(redirectUri); currentUri = redirectUri; continue; } break; } if (redirectChain.Count > 1) { // 发生了redirectChain.Count - 1次重定向,可自行获取链路信息 }
WebResponse相关问题解答
WebResponse是WebRequest体系的专属类,和HttpClient是两套完全独立的HTTP请求实现,无法混用。按照微软官方推荐以及你批量扫描需要复用单例的需求,完全不需要切换到WebRequest,上述HttpClient方案即可满足所有需求。
内容的提问来源于stack exchange,提问作者ThomasRones
相关产品推荐
相关产品推荐

