You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的原因主要有两点:

  1. Cookie头的非法添加:HttpClient的DefaultRequestHeaders不允许直接添加Cookie头,这类头属于受保护的特殊头,需要通过CookieContainer来管理。手动添加的Cookie头会被HttpClient自动忽略,导致请求没有携带会话Cookie,服务器无法识别你的会话,因此返回404(该接口可能需要会话验证才能访问)。而第一种方式的AddHeaders方法大概率内部做了特殊处理,比如将Cookie存入CookieContainer而非直接添加到DefaultRequestHeaders。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:41:18