C# HttpClient手动设置sessionHeaders后返回404错误的原因排查
HttpClient手动设置请求头导致404错误的原因及潜在陷阱
我正在开发一个C#应用,使用HttpClient向服务器发送HTTP请求查询可用日期。采用两种不同方式配置请求头,仅一种可行,另一种返回404错误。
可行代码
此代码通过sessionHeaders及额外请求头完成配置:
private Dictionary<string, string> ExtractHeaders(HttpResponseMessage response) { var cookies = ExtractRelevantCookies(response); var html = response.Content.ReadAsStringAsync().Result; // Parse HTML to extract the CSRF token var doc = new HtmlDocument(); doc.LoadHtml(html); var csrfTokenNode = doc.DocumentNode.SelectSingleNode("//meta[@name='csrf-token']"); var csrfToken = csrfTokenNode?.Attributes["content"].Value; var baseUri = "some url"; // Return the headers as a dictionary return new Dictionary<string, string> { { "Cookie", cookies }, { "X-CSRF-Token", csrfToken }, { "Referer", baseUri }, { "Referrer-Policy", "strict-origin-when-cross-origin" }, { "User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" }, { "Cache-Control", "no-store" }, { "Connection", "keep-alive" } }; } private async Task<DateTime?> CheckDate(Dictionary<string, string> sessionHeaders) { var url = $"some url"; _httpClient.DefaultRequestHeaders.Clear(); AddHeaders(sessionHeaders, _httpClient); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); _httpClient.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest"); var response = await _httpClient.GetAsync(url); var responseData = await response.Content.ReadAsStringAsync(); return null; }
不可行代码
第二种方式通过DefaultRequestHeaders手动设置请求头,会触发HTTP 404错误:
private Dictionary<string, string> ExtractHeaders(HttpResponseMessage response) { var cookies = ExtractRelevantCookies(response); var html = response.Content.ReadAsStringAsync().Result; var doc = new HtmlDocument(); doc.LoadHtml(html); var csrfTokenNode = doc.DocumentNode.SelectSingleNode("//meta[@name='csrf-token']"); var csrfToken = csrfTokenNode?.Attributes["content"].Value; return new Dictionary<string, string> { { "Cookie", cookies }, { "X-CSRF-Token", csrfToken } }; } private async Task<DateTime?> CheckDate(Dictionary<string, string> sessionHeaders) { var url = $"some url"; _httpClient.DefaultRequestHeaders.Clear(); // Manually add sessionHeaders foreach (var header in sessionHeaders) { _httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); } // Add additional headers _httpClient.DefaultRequestHeaders.Add("Referrer", "some url"); _httpClient.DefaultRequestHeaders.Add("Referrer-Policy", "strict-origin-when-cross-origin"); _httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"); _httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoStore = true }; _httpClient.DefaultRequestHeaders.Connection.Add("keep-alive"); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); _httpClient.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest"); var response = await _httpClient.GetAsync(url); var responseData = await response.Content.ReadAsStringAsync(); return null; }
附:ExtractRelevantCookies方法
private string ExtractRelevantCookies(HttpResponseMessage response) { var cookies = response.Headers.GetValues("Set-Cookie"); var parsedCookies = ParseCookies(cookies); return $"session={parsedCookies["session_session"]}"; }
问题原因及分析
两种方式的核心差异导致404的原因主要有两点:
- Cookie头的非法添加:HttpClient的
DefaultRequestHeaders不允许直接添加Cookie头,这类头属于受保护的特殊头,需要通过CookieContainer来管理。手动添加的Cookie头会被HttpClient自动忽略,导致请求没有携带会话Cookie,服务器无法识别你的会话,因此返回404(该接口可能需要会话验证才能访问)。而第一种方式的AddHeaders方法大概率内部做了特殊处理,比如将Cookie存入CookieContainer而非直接添加到DefaultRequestHeaders。 - Referer头拼写错误:不可行代码中添加的是
Referrer头(多了一个r),而HTTP标准中的正确头名是Referer。部分服务器会严格校验请求头名称,错误的头名会被视为无效,导致请求缺少必要的Referer信息,服务器拒绝返回正确内容,返回404。
手动设置HttpClient请求头的潜在陷阱
- 特殊头的限制:
Cookie、Host、Content-Length等属于受保护头,不能直接用DefaultRequestHeaders.Add添加,必须使用对应的API(比如CookieContainer处理Cookie,HttpClient自动维护Host头)。 - 头名称大小写/拼写问题:虽然HTTP标准规定头名不区分大小写,但不少服务器会严格校验拼写,像
Referer写成Referrer这类错误会导致头不被识别。 - 重复添加头:多次调用
Add方法添加同一个头会生成多个相同的请求头,部分服务器会判定请求非法。 - 复用HttpClient的残留问题:即使调用了
DefaultRequestHeaders.Clear(),某些系统默认头或之前请求的残留头可能仍会影响当前请求,尤其是HttpClient被复用的场景。 - 结构化头的错误处理:像
Cache-Control这类结构化头,直接添加字符串和使用CacheControlHeaderValue对象的处理逻辑不同,前者可能出现格式错误。
内容的提问来源于stack exchange,提问作者chatay
相关产品推荐
相关产品推荐

