如何使 HttpClient 忽略 Content-Length 标头

Posted

技术标签:

【中文标题】如何使 HttpClient 忽略 Content-Length 标头【英文标题】:How to make HttpClient ignore Content-Length header 【发布时间】:2016-02-02 08:08:04 【问题描述】:

我正在使用 HttpClient 与我无权访问的服务器进行通信。有时来自服务器的 JSON 响应会被截断。

当 Content-Length 标头小于应有的值(8192 与 8329)时,就会出现问题。这似乎是服务器上的一个错误,它提供的 Content-Length 标头比响应正文的实际大小更小。如果我使用谷歌浏览器而不是 HttpClient,响应总是完整的。

因此,我想让 HttpClient 忽略错误的 Content-Length 标头并读取到响应的末尾。有可能这样做吗?任何其他解决方案都非常受欢迎。谢谢!

这是我的 HttpClient 的代码:

var client = new HttpClient();
client.BaseAddress = new Uri(c_serverBaseAddress);

HttpResponseMessage response = null;
try

      response = await client.GetAsync(c_serverEventApiAddress + "?location=" + locationName);

catch (Exception e)

    // Do something

var json = response.Content.ReadAsStringAsync().Result;

var obj = JsonConvert.DeserializeObject<JObject>(json); // The EXCEPTION occurs HERE!!! Because the json is truncated!

编辑 1:

如果我使用 HttpWebRequest,它可以完全读取到 JSON 响应的末尾而不会被截断。但是,我想使用 HttpClient,因为它有更好的 async/await。

这是使用 HttpWebRequest 的代码:

var url = c_serverBaseAddress + c_serverEventApiAddress + "?location=" + "Saskatchewan";

var request = (HttpWebRequest)WebRequest.Create(url); 
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";

var response = (HttpWebResponse)request.GetResponse();

StringBuilder stringBuilder = new StringBuilder(); 
using (StreamReader reader = new StreamReader(response.GetResponseStream()))

      string line;
      while ((line = reader.ReadLine()) != null)
      
            stringBuilder.Append(line);
      

var json = stringBuilder.ToString();  // COMPLETE json response everytime!!!

【问题讨论】:

因此,使用 Chrome 进行的相同调用显示了有效的 JSON 响应,但使用 HttpClient,您在示例中的 json 变量中得到了一个不完整的 JSON 对象? 正确。有时 HttpClient 返回一个不完整的 JSON 响应,有时它返回一个完整的响应。不完整的 JSON 总是与较小的 Content-Length 标头一起出现。 服务器返回的整个 JSON 响应的 Content-Length 错误,或者响应实际上被截断了? 服务器返回整个 JSON。 Chrome 可以毫无问题地检索它,如果我使用 HttpWebRequest 它可以读取到完整 JSON 的末尾。我正在更新问题以包含使用 HttpWebRequest 的代码。 我最终使用 HttpWebRequest 作为解决方法。使用 TaskFactory.FromAsync,使用 HttpWebRequest 进行异步调用非常容易。参考:***.com/questions/202481/… 【参考方案1】:

您可以尝试指定响应内容的缓冲区大小

var client = new HttpClient();
client.MaxResponseContentBufferSize = <your_buffer_size>;

属性 MaxResponseContentBufferSize 的含义:

获取或设置读取响应内容时要缓冲的最大字节数。

【讨论】:

以上是关于如何使 HttpClient 忽略 Content-Length 标头的主要内容,如果未能解决你的问题,请参考以下文章

如何使发射器忽略大小写?

如何忽略 Apache HttpComponents HttpClient 5.1 中的 SSL 证书错误

使用 HttpClient 将 Content-Type 设置为“application/json”并将对象添加到正文

使用 HttpClient 时如何不排除 Content-Type 中的字符集?

httpclient - 如何将 Content-Disposition 设置为“application/json;”在多部分

如何从 HttpClient.PostAsJsonAsync() 生成的 Content-Type 标头中删除 charset=utf8?