Response.Redirect 是 ASP.NET Web Forms 與 MVC 中執行HTTP 重導向的核心方法。許多開發者誤以為它在伺服器端直接轉送請求,實際上它透過HTTP 回應標頭指示瀏覽器發起新請求。
錯誤認知:Response.Redirect("default1.aspx") 在伺服器內部將執行流轉移至目標頁面。
正確認知:它向用戶端發送 HTTP 302 Found** 回應,包含 Location 標頭,瀏覽器隨後對新 URL 發起 GET 請求。
用戶端 伺服器端
| |
|---- GET /page1.aspx ------------------->|
| | 處理邏輯
| | Response.Redirect("page2.aspx")
|<--- HTTP 302 Found ---------------------|
| Location: /page2.aspx |
| |
|---- GET /page2.aspx ------------------->| (新請求,新生命週期)
| |
|<--- HTTP 200 OK (page2 內容) -----------|
| |
public void Redirect(string url) {
Redirect(url, false); // endResponse = false
}
public void Redirect(string url, bool endResponse) {
if (url == null) throw new ArgumentNullException(nameof(url));
// 1. 解析相對/絕對 URL
url = ResolveRedirectUrl(url); // 處理 ~/, 應用程式路徑等
// 2. 設定狀態碼 302
StatusCode = 302; // HttpStatusCode.Found
// 3. 設定 Location 標頭 (核心步驟)
RedirectLocation = url; // 內部設定 "Location" 標頭
// 4. 清除回應內容主體 (重導向不需內容)
ClearContent();
// 5. 可選:立即結束回應執行緒
if (endResponse) {
End(); // 呼叫 Thread.CurrentThread.Abort() (舊版) 或 HttpApplication.CompleteRequest()
}
}
endResponse| 值 | 行為 | 適用場景 |
|---|---|---|
true (預設) | 呼叫 Response.End(),拋 ThreadAbortException 終止當前執行緒,後續程式碼不執行。 | 傳統 Web Forms、需立即中斷流程 |
false | 不終止執行緒,後續程式碼繼續執行,但回應已設定重導向。 | MVC、Web API、需執行後續邏輯 (如記錄日誌) |
ASP.NET MVC 控制器動作應回傳 RedirectResult 或 RedirectToRouteResult,而非直接呼叫 Response.Redirect:
// 推薦
public ActionResult Login() {
// 驗證邏輯
return RedirectToAction("Index", "Home"); // 302 重導向
// 或指定 URL
return Redirect("~/Dashboard");
// 或永久重導向 (301)
return RedirectPermanent("https://newsite.com");
}
// 不推薦
public ActionResult Login() {
Response.Redirect("/Home/Index"); // 繞過 MVC 結果管線
return new EmptyResult(); // 仍需回傳 ActionResult
}
| 問題 | 原因 | 解決方案 |
|---|---|---|
| 重導向後 Session 遺失 | Cookieless session 或跨域重導向 | 確保 Cookie 正常、同域重導向、檢查 web.config sessionState 設定 |
| UpdatePanel 部分更新中重導向失效 | AJAX 回應無法處理 302 | 使用 ScriptManager.RegisterStartupScript 註冊 window.location.href 客戶端跳轉 |
| 大量資料下載後重導向 | 回應標頭已發送無法修改 | 先重導向至下載頁,由該頁觸發下載 (iframe/JS) 或使用 Content-Disposition: attachment |
| ThreadAbortException 擾亂日誌 | endResponse=true 預設行為 | MVC 使用 return Redirect(...);Web Forms 關鍵處用 Response.Redirect(url, false) + Context.ApplicationInstance.CompleteRequest() |
Response.Redirect 預設。POST 可能變 GET (歷史行為)。RedirectPermanent。Redirect(url, false) + 手動設 StatusCode=307。Response.Redirect 本質是發送 HTTP 302 回應,由瀏覽器發起新請求。return Redirect(...) 系列方法,融入結果管線。endResponse 參數差異,避免 ThreadAbortException 副作用。