Why can the C# HttpClient not call this URL (always times out)?(为什么C#HttpClient不能调用此URL(总是超时)?)
问题描述
我一直在开发一个确定有关网页信息的应用程序。其中一个组件涉及向URL发出HTTP GET请求,获取并分析该HTML。除了一个以外,我用过的每一个URL都运行得很好...
罪魁祸首是.NETHttpClient
,它似乎总是在请求问题域内的任何URL时超时。然而,浏览器请求的相同URL在毫秒内返回内容。有关标头的信息似乎没有什么异常。
增加超时只会导致它需要更长的时间来轰炸。我试了几分钟,结果是一样的。我尝试了各种方法,比如将用户代理字符串设置为Chrome,但都无济于事。
有问题的域是:http://careers.adidas-group.com
注意:同一站点也在https://careers.adidas-group.com运行在HTTPS上(它拥有有效的证书)。
使用任一协议都会导致相同的错误。
我可以用一个简单的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(() => )
使其与示例中同步Main方法的上下文一起工作。但这对结果没有影响。(实际的例外是"任务已取消",但这似乎是超时的征兆,而不是实际问题)。
谁能解释一下为什么会发生这种情况(是服务器配置的问题吗?)我可以做些什么来让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的VS 2017中),但当部署到实时环境中时(在IIS 7.5/Windows服务器中运行),它仍然不起作用。与控制台应用程序版本相同-适用于本地PC,不适用于服务器。我试了3台Windows服务器,相同的代码,在其中一台上运行,而在另外两台上不行。不可思议。进一步编辑-A解决方案?
进一步阅读后,似乎certain web-servers,例如Akamai Ghost(托管有问题的域)具有一些相当复杂的"bot"检测,可以拒绝来自未知客户端的连接。措施包括检查HTTP请求头的顺序,以便它们与用户代理正常发送的内容匹配(即,如果您将用户代理字符串伪装为Chrome,您最好像Chrome一样,按照Chrome的操作顺序发送标头并接受相同的内容类型等)。
在尝试伪造许多浏览器用户代理字符串后,我最终发现"假装"是Google PageSpeedbot奏效了。将用户代理字符串设置为:"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服务器或.NET框架,这似乎都有效。
我最终得出的标题是:
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#HttpClient不能调用此URL(总是超时)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么C#HttpClient不能调用此URL(总是超时)?
- 在 C# 中异步处理项目队列 2022-01-01
- 使用 rss + c# 2022-01-01
- C# 通过连接字符串检索正确的 DbConnection 对象 2022-01-01
- 为什么 C# 中的堆栈大小正好是 1 MB? 2022-01-01
- 是否可以在 .Net 3.5 中进行通用控件? 2022-01-01
- 在 LINQ to SQL 中使用 contains() 2022-01-01
- Azure Active Directory 与 MVC,客户端和资源标识同一 2022-01-01
- Windows 喜欢在 LINUX 中使用 MONO 进行服务开发? 2022-01-01
- 带问号的 nvarchar 列结果 2022-01-01
- CanBeNull和ReSharper-将其用于异步任务? 2022-01-01