我一直在开发一个确定网页信息的应用程序。其中一个组件涉及对url发出http get请求,获取html并对其进行分析。这对我抛出的每个url都很有用,除了一个……
罪魁祸首是.netHttpClient它似乎总是超时请求问题域中的任何url。但是,浏览器请求的相同url在毫秒内返回内容。头上没有什么异常。
延长超时时间只会导致爆炸所需的时间更长。我试过几分钟也有同样的结果。我尝试过各种方法,比如将用户代理字符串设置为chrome的字符串,但都没有成功。
所讨论的域是:http://careers.adidas-group.com
注意,同一个站点也运行在https上的https://careers.adidas-group.com(它有一个有效的证书)。
使用任一协议都会导致相同的错误。
我可以用一个简单的C控制台应用程序显示问题,如下所示:

static void Main(string[] args)
{
    string url = "http://careers.adidas-group.com";

    var client = new HttpClient
    {
        Timeout = TimeSpan.FromSeconds(10)
    };

    using (var message = new HttpRequestMessage(HttpMethod.Get, url))
    {
        using (var httpResponse = Task.Run(() => client.SendAsync(message)).Result)
        {
            Console.WriteLine("{0}: {1}", httpResponse.StatusCode, httpResponse.ReasonPhrase);
        }
    }

    Console.ReadLine();
}

注意在上面的例子中,我将超时设置为10秒,这只是为了加速问题的解决-但是,增加超时没有区别。
具有不同url的相同代码(例如https://stackoverflow.com/)运行良好。
另外请注意,上面的代码被简化为作为控制台应用程序运行。我的实际代码在异步MVC控制器方法中正确地异步运行(使用await)-我只是使用Task.Run(() => )使它在示例中与同步主方法的上下文一起工作。但这对结果没有影响。(实际的例外情况是“任务已取消”,但这似乎是超时的问题,而不是实际问题)。
有谁能向我解释一下为什么会发生这种情况(这与服务器配置有关吗?)如果有什么需要的话,我能做些什么来让httpclient满足这个请求呢?谢谢。

最佳答案

好吧,经过大量调查,我决定一定是服务器在请求中查找特定的头。因此,我检查了大多数浏览器发送的内容,复制了这些内容,最后将其缩减到服务器,要求显示以下所有标题:

client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.Add("Accept-Language", "en-GB,en;q=0.9,en-US;q=0.8");

删除其中任何一个,服务器都不会响应。很奇怪!
感谢所有看过这篇文章的人,我希望这个答案能对将来的人有所帮助:)
编辑-更怪异
好吧,这种奇怪的情况现在还在继续,因为即使这解决了本地运行的问题(与iis express的2017年相比),部署到实时环境(在iis 7.5/windows服务器上运行)时仍然无法工作。与控制台应用程序版本相同-适用于本地PC,不适用于服务器。尝试了3个windows服务器,相同的代码,并且在其中一个上工作,而在另外两个上不工作。比扎尔。
进一步编辑-决议?
因此,在进一步阅读之后,它似乎certain web-servers,例如,akama ghost(托管有问题的域)有一些相当复杂的“bot”检测,拒绝来自未知客户端的连接。措施包括检查http请求头的顺序,以便它们与用户代理通常发送的内容相匹配(即,如果您将用户代理字符串伪装为chrome,则您的行为最好与chrome完全相同,按chrome的顺序发送头,并接受相同的内容类型等)。
在尝试伪造大量浏览器用户代理字符串后,我最终发现“假装”为google pagespeed bot有效,即将用户代理字符串设置为:“Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Page Speed Insights) Chrome/27.0.1453 Safari/537.36
无论使用的是哪种版本的Windows Server或.NET Framework,这似乎都能正常工作。
我最终想到的标题是:
this.Client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/apng,*/*;q=0.8");
this.Client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
this.Client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
this.Client.DefaultRequestHeaders.Add("Accept-Language", "en-GB,en;q=0.9,en-US;q=0.8");
this.Client.DefaultRequestHeaders.Add("Connection", "keep-alive");
this.Client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
this.Client.DefaultRequestHeaders.Add("Pragma", "no-cache");
this.Client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Page Speed Insights) Chrome/27.0.1453 Safari/537.36");

关于c# - 为什么C#HttpClient不能调用此URL(总是超时)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48790438/

10-09 08:14
查看更多