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

ASP.NET Request.UrlReferrer 中文亂碼徹底解決:分段編碼法與安全防篡改檢查

     編輯:ASP.NET 基礎

問題根因

`Request.UrlReferrer` 回傳 `Uri` 物件,其 `Query` 屬性已自動 **URL 解碼**。若原始 Referer URL 含中文參數且瀏覽器編碼非 UTF-8 (如舊版 IE 送 GB2312),`Uri` 解碼時預設用 UTF-8 導致亂碼。**直接對完整 URL `UrlEncode` 無效**,因路徑部分不需編碼且會破壞結構。

核心解法:分段處理 — 路徑保留,參數重新編碼


protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string refererUrl = Request.UrlReferrer?.ToString();
        if (!string.IsNullOrEmpty(refererUrl))
        {
            // 1. 分割路徑與查詢字串
            var uri = new Uri(refererUrl);
            string path = uri.GetLeftPart(UriPartial.Path); // 含 scheme://host/path
            string query = uri.Query; // 含前導 '?',已被錯誤解碼

            // 2. 將查詢字串按原始位元組重新編碼為 GB2312 (或目標編碼)
            // 關鍵:先取得錯誤解碼後的字串對應的位元組 (預設 UTF-8 解碼產生的位元組)
            // 再按正確編碼 (GB2312) 解碼回字串,最後再 UrlEncode
            // 簡化做法:假設瀏覽器原始送 GB2312,伺服器誤用 UTF-8 解碼
            // 實際專案建議統一全站 UTF-8,避免此問題
            byte[] utf8Bytes = Encoding.UTF8.GetBytes(query);
            string correctedQuery = Encoding.GetEncoding("GB2312").GetString(utf8Bytes);
            
            // 3. 重新 UrlEncode (UTF-8) 供後續安全使用
            string safeQuery = HttpUtility.UrlEncode(correctedQuery, Encoding.UTF8);
            
            string safeReferer = path + safeQuery;
            ViewState["SafeReferer"] = safeReferer;
        }
    }
}

跳轉時解碼還原


Response.Redirect(HttpUtility.UrlDecode(ViewState["SafeReferer"]?.ToString() ?? "~/Default.aspx"));

進階:統一全站 UTF-8 避免編碼地獄 (根治)

  1. `Web.config`:`<globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" />`
  2. 頁面頂端:`<%@ Page ResponseEncoding="utf-8" %>`
  3. HTML Head:`<meta charset="utf-8" />`
  4. 資料庫連線字串:`CharSet=utf8mb4` (MySQL) / 無需特殊設定 (SQL Server 預設 Unicode)。
  5. 前端表單:`
    `
  6. **結果**:瀏覽器送 UTF-8 → IIS 以 UTF-8 解碼 → `Request.UrlReferrer.Query` 正確無亂碼 → 無需任何修補代碼。

安全防篡改:偵測使用者手動修改 URL 參數


protected void Page_Load(object sender, EventArgs e)
{
    try
    {
        // 若使用者手動修改網址列參數並 Enter,Referer 通常為 null 或無 Query
        var _ = Request.UrlReferrer.PathAndQuery; // 觸發存取
    }
    catch
    {
        // Referer 為 null 導致 NullReferenceException
        throw new InvalidOperationException("非法操作:請勿手動修改網址參數。");
    }
}

**原理**:正常連結導航 → `Request.UrlReferrer` 含完整 `PathAndQuery`。手動修改網址列 → 瀏覽器不送 Referer 或送空 → `Request.UrlReferrer` 為 `null` → 存取屬性拋出例外。

**注意**:此法屬「偏門」,Referer 可被防火牆/隱私擴充/代理移除,誤判率高。**正規做法**:

  • 重要參數簽名 (HMAC-SHA256) 或加密 (AES-GCM)。
  • 關鍵操作改 POST + Anti-Forgery Token。
  • 權限檢查基於 `User.Identity` + 資料層 `WHERE UserId = @CurrentUser`,不信任任何客戶端參數。

總結

`Request.UrlReferrer` 中文亂碼核心在於 **瀏覽器編碼與伺服器解碼不一致**。**分段編碼法** (路徑不動、Query 重編) 可修補舊系統;**全站統一 UTF-8** 為根治之道。安全防篡改請採用 **簽名/Token/權限檢查** 正規手段,勿依賴 Referer 側寫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved