C# HttpClient.SendAsync 总是返回 404 但 URL 在浏览器中有效
Posted
技术标签:
【中文标题】C# HttpClient.SendAsync 总是返回 404 但 URL 在浏览器中有效【英文标题】:C# HttpClient.SendAsync always returns 404 but URL works in browser 【发布时间】:2015-11-05 21:08:45 【问题描述】:我正在开发一个 C# 控制台应用程序来测试 URL 是否有效。它适用于大多数 URL。但我们发现在某些情况下,应用程序总是从目标站点获得 404 响应,但 URL 实际在浏览器中有效。当我在 DHC(Dev HTTP 客户端)等工具中尝试这些 URL 时,它们也可以工作。
一开始,我认为这可能是没有添加正确标题的原因。但是在尝试使用 Fiddler 编写具有相同标头的 http 请求后,它可以在 Fiddler 中使用。
那么我的代码有什么问题? .NET HttpClient 中是否有任何错误?
这是我的测试应用程序的简化代码:
class Program
static void Main(string[] args)
var urlTester = new UrlTester("http://www.hffa.it/short-master-programs/fashion-photography");
Console.WriteLine("Test is started");
Task.WhenAll(urlTester.RunTestAsync());
Console.WriteLine("Test is stoped");
Console.ReadKey();
public class UrlTester
private HttpClient _httpClient;
private string _url;
public UrlTester(string url)
_httpClient = new HttpClient
Timeout = TimeSpan.FromMinutes(1)
;
// Add headers
_httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/46.0.2490.80 Safari/537.36");
_httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip,deflate,sdch");
_httpClient.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
_httpClient.DefaultRequestHeaders.Add("Accept-Language", "sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4");
_url = url;
public async Task RunTestAsync()
var httpRequestMsg = new HttpRequestMessage(HttpMethod.Get, _url);
try
using (var response = await _httpClient.SendAsync(httpRequestMsg, HttpCompletionOption.ResponseHeadersRead))
Console.WriteLine("Response: 0", response.StatusCode);
catch (HttpRequestException e)
Console.WriteLine(e.InnerException.Message);
【问题讨论】:
您从该代码中得到的究竟是什么? 一个HTTP请求就是一个HTTP请求;它来自哪里并不重要(除非服务器阻止某些 User-Agent 标头,但即使这也可以更改)。这确实对我来说听起来像是一个标题问题。您是否确认您正在完全复制从浏览器发送的请求?您是否使用过像 Fiddler 这样的工具来准确捕获 HTTP 流量,然后将其复制到您的代码中? @pymaxion 是的。我照你说的做了。我使用 Fiddler 来查看成功的 http 请求中标头的外观。然后在代码中添加这些标题。即使我后来得到了类似的标题,它仍然没有用。 我建议你运行一个像 Wireshark 这样的网络嗅探器,看看到底发生了什么。也许异步客户端也发送了Expect: 100-continue
标头?
@RonKlein 嗨,我尝试添加 _client.DefaultRequestHeaders.ExpectContinue = false,仍然得到 404。
【参考方案1】:
这似乎是接受的语言的问题。使用以下 Accept-Language
标头值时收到 200 响应
_httpClient.DefaultRequestHeaders.Add("Accept-Language", "en-GB,en-US;q=0.8,en;q=0.6,ru;q=0.4");
附言我假设您知道在您的示例中 _client
应该在 urlTester 构造函数中读取 _httpClient
否则它不会构建。
【讨论】:
【参考方案2】:此问题的另一个可能原因是您发送的 url 长度超过大约 2048 个字节。此时内容(几乎可以肯定是查询字符串)可能会被截断,这反过来意味着它可能无法与服务器端路由正确匹配。
虽然这些 url 在浏览器中被正确处理,但在 power shell 中使用 get 命令也失败了。
通过使用带有键值对的 POST 而不是使用带有长查询字符串的 GET 解决了这个问题。
【讨论】:
以上是关于C# HttpClient.SendAsync 总是返回 404 但 URL 在浏览器中有效的主要内容,如果未能解决你的问题,请参考以下文章
在 HttpClient.SendAsync() 之后无法访问已释放的对象
HttpClient.SendAsync() 未将 JSON 作为字符串发送