HttpClient - 检测 Content-Type

9

我需要检测特定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;
        }
    }

1
我想象中,该问题中的功能取决于服务器发送响应。它可能不会遵守请求,而是无论如何都会将所有内容发送给您。 - Liam
WebException无法处理GetAsync方法的所有可能异常。您应该考虑更广泛的捕获。请参阅https://msdn.microsoft.com/en-us/library/windows/apps/dn298646.aspx?f=255&MSPPError=-2147217396。 - Mehrzad Chehraz
1
@Richard 在这里看答案。他们使用 HttpClient 有什么问题吗?如果没有问题,那么这个问题就不是重复的。 - Yam Marcovic
1
@YamMarcovic 首先这是一个重复问题:另一个问题询问的是仅获取头信息,因此提取Content-Type。其次,我检查了HttpClient是否有一个带有HTTP方法参数的Get重载(但错过了另一种方法)。无论如何,其他问题回答了这个问题(即使它使用了不同的类型)。 - Richard
1
@Richard,即使是在标题中,这个问题也涉及到HttpClient类。按照你的推理,你可能会将其标记为重复,因为有一个等效的Python实现的答案。 - Yam Marcovic
显示剩余6条评论
2个回答

7

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

HTTP完成选项值,指示何时应将操作视为已完成。

来自MSDN的ResponseHeadersRead:

操作应在响应可用且已读取标题时完成。尚未读取内容。

然后,如果需要,您可以处理客户端。

// 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请求--参考文献?这是一个大问题,因为您将不必要地为您和服务器使用带宽。 - Yam Marcovic
@YamMarcovic 我是基于经验而言的。 - Mehrzad Chehraz

4
现在来看看相关的IT技术。如何呢?
var response = await client.SendAsync(
  new HttpRequestMessage(HttpMethod.Head, url)
);

1
@Liam 根据RFC 2616,“9.4 HEADHEAD方法与GET方法相同,但服务器在响应中不得返回消息正文。” - Yam Marcovic
1
你的意思是 HttpMethod.Head 这一部分,你没有解释得很清楚。 - Liam
1
根据Web服务器的实现,可能不支持“HEAD”。建议回退到“GET”。 - mausworks
我在过去的几年中使用过的一些API无法遵守“HEAD”规范。 - mausworks
1
@YamMarcovic 这当然取决于具体的实现方式。如果它是针对一个已知遵循“HEAD”规范的Web服务进行实现的,那么可以毫不犹豫地不需要回退。在执行“GET”请求之前检查响应,因此不需要浪费带宽。 - mausworks
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接