c# - 当服务器返回 HTTP 302 Found using HttpClient in C# 为什么我不能下载文件?
问题描述
我在下载文件时遇到问题,该文件最终在 302 后返回。
假设我有一个这样的 URL:https://myhost/export/myfile.php。当我在浏览器中导航到此 URL 时,文件会下载。
但是,我想使用 C# 下载文件。
这是我尝试过的使用HttpClient
,但不起作用:
var uri = "https://myhost/export/myfile.php";
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
using (var client = new HttpClient(handler))
{
var response = await client.SendAsync(requestMessage);
if (response.IsSuccessStatusCode)
{
/// it never reach here because 302 is not sucess status code
}
}
我也尝试过使用WebClient
:
var url = "https://myhost/export/myfile.php";
using (var webclient = new WebClient())
{
var response = await _webClient.DownloadDataTaskAsync(url); // throws an exception regarding HTTP status being 302 Found
string download = Encoding.ASCII.GetString(response);
}
如何下载重定向后返回的文件?
---------问题解决了------------ 经过@Ermiya Eskandary 的支持,我终于找到了根本原因。此请求缺少身份验证所需的标头名称“Cookie”(我用 cookie => 错误的请求配置误解了它)。感谢上帝派这个人来帮助我。
解决方案
状态码为302的 HTTP 响应表示请求的信息位于Location
响应标头中指定的 URI(本质上是重定向)。
考虑到您已设置HttpClientHandler.AllowAutoRedirect
,处理程序将自动遵循 HTTP 重定向标头,直到您到达没有指示重定向的状态代码的响应。
我也不怀疑服务器将您重定向超过 50 次,这是默认值,HttpClientHandler.MaxAutomaticRedirections
因此只剩下一件事。
一旦响应完成,无论出于何种原因,服务器实际上都会返回一个失败的状态代码,或者如果它不是,那么需要注意的一个重要注意事项是,除非您使用的是 .NET Framework(而不是 .NET Core 等)。 ),HttpClient
不会遵循从安全 HTTPS 端点到不安全 HTTP 端点的重定向。
出于安全原因,您不能覆盖不允许 HTTPS -> HTTP 的自动重定向,但是如果必须,请自行解析Location
标头,直到重定向完成。
这应该有效:
var uri = "https://myhost/export/myfile.php";
var initialRequestMessage = new HttpRequestMessage(HttpMethod.Get, URI);
initialRequestMessage.Headers.Add("Cookie", "PHPSESSID=...");
using (var client = new HttpClient())
{
var response = await client.SendAsync(initialRequestMessage);
while (response.StatusCode == HttpStatusCode.Found)
{
Uri redirectedUri = response.Headers.Location;
var requestMessage = new HttpRequestMessage(HttpMethod.Get, redirectedUri);
response = await client.SendAsync(requestMessage);
}
// response is successful or unsuccessful but will not be a redirect
Console.WriteLine(response.StatusCode);
}
推荐阅读
- javascript - Google Sheets Api 不使用 .json 文件,而是将其嵌入 python 代码中
- multithreading - 为什么在涉及线程时需要“move”关键字;为什么我永远不想要这种行为?
- flutter - 从 StreamBuilder 获取有效值
和一个孩子 StreamBuilder - google-sheets - 谷歌应用脚本将多个工作表动态合并到一个主文件中
- ckeditor5 - 样式化 CKEditors 的单个实例的方式?
- amazon-web-services - 一旦它变得健康,有没有办法让 LB 将流量路由到主机?
- c# - 如何使用物理改变子弹射击速度并保持子弹射击距离?
- dryioc - 使用工厂类解析 DryIoc serviceKey 实现
- javascript - 如何获取 JavaScript 以确保没有字段为空
- javascript - 2020 年 Instagram 追随者计数端点