首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 頁面返回上一頁實作:Request.UrlReferrer 完整應用指南

     編輯:ASP.NET 基礎

登入、操作完成後返回上一頁是常見需求。`Request.UrlReferrer` 提供 HTTP Referer 標頭資訊,但有**多種邊界情況需妥善處理**。

核心屬性

Uri referrer = Request.UrlReferrer; // 可能為 null
string referrerUrl = referrer?.ToString();

Referer 為 null 的常見情況

健壯返回邏輯實作

1. 登入頁面:儲存 Referer 至 ViewState/Session

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // 優先取得 Referer
        if (Request.UrlReferrer != null)
        {
            ViewState["ReturnUrl"] = Request.UrlReferrer.ToString();
        }
        // 次優先:QueryString 指定(如 ?ReturnUrl=/order/detail/123)
        else if (!string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
        {
            ViewState["ReturnUrl"] = Request.QueryString["ReturnUrl"];
        }
    }
}

2. 登入成功後:按優先順序導向

protected void btnLogin_Click(object sender, EventArgs e)
{
    if (ValidateUser(txtUser.Text, txtPass.Text))
    {
        Session["User"] = user;
        
        string returnUrl = null;
        
        // 1. ViewState(同一 Session 內的上一頁)
        if (ViewState["ReturnUrl"] != null)
            returnUrl = ViewState["ReturnUrl"].ToString();
        
        // 2. Session(跨頁面保持)
        else if (Session["ReturnUrl"] != null)
            returnUrl = Session["ReturnUrl"].ToString();
        
        // 3. 當前 Request 的 Referer(最後防線)
        else if (Request.UrlReferrer != null)
            returnUrl = Request.UrlReferrer.ToString();
        
        // 4. 預設首頁
        if (string.IsNullOrEmpty(returnUrl) || !IsLocalUrl(returnUrl))
            returnUrl = "~/Default.aspx";
        
        Response.Redirect(returnUrl);
    }
    else
    {
        ShowError("帳號或密碼錯誤");
    }
}

3. 安全驗證:防止開放式重導向攻擊

private bool IsLocalUrl(string url)
{
    if (string.IsNullOrEmpty(url)) return false;
    
    Uri absoluteUri;
    if (Uri.TryCreate(url, UriKind.Absolute, out absoluteUri))
    {
        // 必須同域名、同協定、同埠
        return absoluteUri.Host == Request.Url.Host 
            && absoluteUri.Scheme == Request.Url.Scheme
            && absoluteUri.Port == Request.Url.Port;
    }
    
    // 相對路徑視為安全
    return url.StartsWith("/") || url.StartsWith("~/");
}

進階:表單 Post 後返回(PRG 模式)

protected void btnSave_Click(object sender, EventArgs e)
{
    if (SaveData())
    {
        // 成功:導向列表頁(或 Referer),避免重新整理重複提交
        string returnUrl = ViewState["ReturnUrl"]?.ToString() ?? "~/List.aspx";
        Response.Redirect(returnUrl);
    }
    else
    {
        // 失敗:停留當前頁顯示錯誤
        ShowError("儲存失敗");
    }
}

替代方案比較

情況原因應對
直接在瀏覽器輸入網址無前一頁導向預設首頁
HTTPS → HTTP 跨協定瀏覽器安全策略不送 Referer全站 HTTPS 避免
`Response.Redirect` / `Server.Transfer` 後非使用者點擊導航自行儲存返回網址
`window.location.href` / `location.replace` JS 導向部分瀏覽器不送 Referer用 `` 或表單提交
書籤/收藏夾直接開啟無前一頁導向預設首頁
防毒/防火牆/隱私外掛過濾移除 Referer 標頭備援機制
Meta Refresh / ``不送 Referer避免使用

最佳實務總結

  1. **主要依賴 `ReturnUrl` 參數** 明確傳遞(連結產生時附加)
  2. **輔助 `Request.UrlReferrer`** 作為備援
  3. **Session/ViewState** 保持登入等跨頁面流程
  4. **必須驗證 `IsLocalUrl`** 防止開放式重導向漏洞
  5. **提供預設落點**(首頁/儀表板)避免迴圈

建立統一的 `RedirectHelper` 類別封裝上述邏輯,全專案一致呼叫,即可確保返回導向行為可預期、安全、使用者友善。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方案優點缺點適用場景
`Request.UrlReferrer`零成本、自動不可靠、易被過濾輔助參考
QueryString `ReturnUrl`明確、可控、可書籤URL 較長**推薦主要方式**
Session/ViewState 儲存跨請求保持Session 佔用記憶體登入流程、多步驟精靈
HTML5 History API (JS)前端完全控制需 JS 支援、SPA 適用現代前端架構