網頁被無痕重導時取得目的網址 (PowerShell/.NET/.NET Core)
0 |
由前天的範例,我們觀察到 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
Tips of how to get redirected URL with PowerShell/.NET Framework/.NET Core.
Comments
Be the first to post a comment