【问题标题】:HttpClient - detect Content-Type [duplicate]HttpClient - 检测 Content-Type [重复]
【发布时间】:2016-04-25 00:09:38
【问题描述】:

我需要检测位于特定 URL 上的内容类型。所以我创建了一个方法来获取响应的 Content-Type。对于小文件和 HTML 页面,它可以正常工作,但如果 URL 指向一个大文件,请求需要很长时间 - 它会在后台获取整个内容(文件)。那么,是否可以在收到Content-Type 标头后立即取消请求并返回结果?

我目前的实现:

    public async static Task<string> GetContentType(string url)
    {
        try
        {
            using (HttpClient client = new HttpClient())
            {
                var response = await client.GetAsync(url);
                if (!response.IsSuccessStatusCode)
                {
                    return null;
                }

                return response.Content.Headers.ContentType.MediaType;
            }
        }
        catch (HttpRequestException)
        {
            return null;
        }
    }

【问题讨论】:

  • 我想该问题中的功能取决于发送响应的服务器。它可能不尊重请求,只是将所有内容都发送给您
  • HttpClient 无法做到这一点,但WebHttpRequest 允许。
  • @Richard 在此处查看答案。他们使用 HttpClient 有什么问题?另外,如果没有问题,那么这个问题不是重复的。
  • @YamMarcovic 首先它是重复的:只获取标题,因此提取 Content-Type 是其他 Q 所要求的。其次,我检查了HttpClientGet 重载,它采用了HTTP 方法参数(但错过了另一种方法)。无论如何,另一个 Q 回答了这个问题(即使它确实使用了不同的类型)。
  • @Richard 这个问题,即使在其标题中,也涉及 HttpClient 类。根据您的推理,您不妨将其标记为重复,因为有一个等效的 Python 实现的答案。

标签: c# .net content-type dotnet-httpclient


【解决方案1】:

由于并非所有服务器都按预期响应 HEAD 请求,因此如果您使用 HttpCompletionOption.ResponseHeadersRead 作为第二个参数,您还可以使用 GetAsync 方法的此重载,以便在收到标头后该方法立即返回。

指示操作何时执行的 HTTP 完成选项值 应该算是完成了。

ResponseHeadersRead 来自 MSDN:

操作应在响应可用后立即完成,并且 标题被读取。内容尚未阅读。

然后您可以根据需要处置客户端。

// Send request to get headers
 response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);

// Check status code
if (!response.IsSuccessStatusCode) {
  // Error...
}

// Get Content Headers
HttpContentHeaderCollection contentHeaders = response.Content.Headers;


// Make decision and dispose client if you wish
if (...) {
   client.Dispose();
}

【讨论】:

  • “由于并非所有服务器都按预期响应 HEAD 请求”——参考?这很重要,因为您将不必要地耗尽您和服务器的带宽。
  • @YamMarcovic 我是根据经验这么说的。
【解决方案2】:

现在怎么样

var response = await client.SendAsync(
  new HttpRequestMessage(HttpMethod.Head, url)
);

【讨论】:

  • @Liam 来自 RFC 2616,“9.4 HEAD HEAD 方法与 GET 相同,只是服务器不得在响应中返回消息体”
  • 所以你得到的是HttpMethod.Head 位。你没有解释得很好......
  • @Liam 这是一段简短且不言自明的代码。
  • 根据网络服务器上的实现,它可能不支持HEAD。建议使用 GET 后备。
  • @YamMarcovic 这当然取决于实现。如果它是针对已知遵守HEAD-spec 的网络服务实施的,那么无论如何;不需要后备。不过,这里不需要浪费带宽,因为您在执行GET-request 之前检查了响应。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-14
  • 2012-02-26
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 2012-05-27
相关资源
最近更新 更多