4

網頁被無痕重導時取得目的網址 (PowerShell/.NET/.NET Core)

 3 years ago
source link: https://blog.darkthread.net/blog/get-redirected-url/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
網頁被無痕重導時取得目的網址 (PowerShell/.NET/.NET Core)-黑暗執行緒

前天的範例,我們觀察到 Invoke-WebRequest -Uri SaveSession.aspx 時因伺服器端 Response.Redirect("ShowSession.aspx"), Invoke-WebRequest 會跳過 HTTP 302 重導過程直接傳回 ShowSession.aspx 的結果。這種無痕重導行為符合大部分的情境要求,但有些例外:若導向目的地非同網站其他頁面而是第三方站台,有時我們需要取得被導向網址以執行不同邏輯。

PowerShell 底層是用 HttpWebRequest 及 HttpWebResponse 實作,故可透過 HttpWebResponse.ResponseUri 取得最終 Response 的網址。以微軟網站為例,當瀏覽器連上 https://www.microsoft.com,會因語系設定被導向 http://www.microsoft.com/zh-tw,如以下範例程式:

$resp = (Invoke-WebRequest -Uri https://www.microsoft.com)
$resp.BaseResponse.ResponseUri.AbsoluteUri

順利得知被導向 http://www.microsoft.com/zh-tw:

以上是 PowerShell 4/5 的做法,PowerShell Core 改以 .NET Core 為基礎,Invoke-WebRequest 也順理成章改用 HttpClient,故寫法有所不同,BaseResponse.ResponseUri.AbsoluteUri 要改成 BaseResponse.RequestMessage.RequestUri.AbsoluteUri。

如果是 .NET 呢?

WebClient 底層也封裝了 HttpWebRequest,只留下 DownloadXXX()、UploadXXX() 等直接取得 string 或 byte[] 的簡單方式,無法存取 ResponseUri。除了回頭改用 HttpWebRequest (參考:如何使用 WebRequest/HttpWebRequest 存取網路資源 by Yowko),stackoverflow 上有網友分享透過繼承 WebClient 存取 protected GetWebResponse() 的巧妙解法,也很符合我的口味。

最後輪到 .NET Core / .NET 5。

借用剛才在 PowerShell Core 學到的 RequestMessage.RequestUri 知識,順利從 HttpClient 傳回結果取出被導向的目的地。

class Program
{
    static void Main(string[] args)
    {
        HttpClient hc = new HttpClient();
        var resp = hc.GetAsync("https://www.microsoft.com").Result;
        Console.Write("導向網址: ");
        Console.WriteLine(resp.RequestMessage.RequestUri);
        Console.WriteLine(resp.Content.ReadAsStringAsync().Result);
    }
}

【參考資料】

Getting Redirected URI’s in Powershell by Jeff Bolduan


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK