簡體   English   中英

當服務器返回使用 C# 中的 HttpClient 發現的 HTTP 302 時,為什么我無法下載文件?

[英]Why can't I download a file when the server returns 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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM