【发布时间】:2019-01-03 15:47:40
【问题描述】:
Windows 上的 .NET Core 2.2 控制台应用程序。
我正在探索如何在 Stackoverflow 共享样式 URL 上使用 HttpClient GetAsync,例如:https://stackoverflow.com/a/29809054/26086,它返回一个带有哈希的 302 重定向 URL
static async Task Main()
{
var client = new HttpClient();
// 1. Doesn't work - has a hash in URL
var url = "https://stackoverflow.com/questions/29808915/why-use-async-await-all-the-way-down/29809054#29809054";
HttpResponseMessage rm = await client.GetAsync(url);
Console.WriteLine($"Status code: {(int)rm.StatusCode}"); // 400 Bad Request
// 2. Does work - no hash
url = "https://stackoverflow.com/questions/29808915/why-use-async-await-all-the-way-down/29809054";
rm = await client.GetAsync(url);
Console.WriteLine($"Status code: {(int)rm.StatusCode}"); // 200 Okay
// 3. Doesn't work as the 302 redirect goes to the first URL above with a hash
url = "https://stackoverflow.com/a/29809054/26086";
rm = await client.GetAsync(url);
Console.WriteLine($"Status code: {(int)rm.StatusCode}"); // 400 Bad Request
}
我正在爬我的博客,里面有很多这么短的代码。
更新/解决方法 感谢@rohancragg,我发现关闭 AutoRedirect 然后从返回的标头中获取 URI 是可行的
// as some autoredirects fail due to #fragments in url, handle redirects manually
var handler = new HttpClientHandler { AllowAutoRedirect = false };
var client = new HttpClient(handler);
var url = "https://stackoverflow.com/a/29809054/26086";
HttpResponseMessage rm = await client.GetAsync(url);
// gives the desired new URL which can then GetAsync
Uri u = rm.Headers.Location;
【问题讨论】:
-
发送到服务器的 URL 不包含
#片段。它仅在客户端中使用,例如浏览器。 -
有道理,谢谢。我正在研究为什么它现在给出 400,因为我希望 HttpClient 忽略散列。我已更新问题以突出显示我需要这样做的原因,即 StackOverflow 共享网址。
-
正如@Damien_The_Unbeliever 所暗示的那样,您只需要去掉散列和之后的所有内容 - 所做的就是告诉浏览器跳转到 HTML 页面中的锚标记(请参阅:@987654322 @)。所以这意味着在这种情况下,您的选项 2 是您唯一的选择...
-
您也可以使用 Uri 类来解析 Uri 并忽略任何“片段”:docs.microsoft.com/en-us/dotnet/api/system.uri.fragment
-
谢谢@rohancragg - 但是如果我请求stackoverflow.com/a/29809054/26086 然后返回302,并自动请求其中包含哈希的URL。也许我必须停止自动重定向stackoverflow.com/a/10647245/26086,然后去掉哈希,然后再做一个请求。