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

ASP.NET Application_AcquireRequestState 導致 AJAX 載入失敗:IIS6/IIS7 差異與解決方案

     編輯:ASP.NET 基礎

問題現象

開發環境(IIS 7/7.5/8/10)一切正常,部署至 IIS 6 後,頁面重新整理時頻繁出現「AJAX 用戶端架構無法載入」錯誤(Sys.WebForms.PageRequestManagerParserErrorException 或 ScriptResource.axd/WebResource.axd 載入失敗)。

問題程式碼

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    string oldToken = Session["token"].ToString(); // 直接存取 Session,未判斷 null
}

根本原因分析

  1. 事件觸發時機:Application_AcquireRequestState 在 ASP.NET 取得與目前要求關聯的 Session 狀態時觸發。
  2. IIS 6 處理 .axd 請求方式不同:ASP.NET AJAX 的 ScriptResource.axd、WebResource.axd 等靜態資源請求,在 IIS 6 下會經過完整 ASP.NET 管線,因此每一個 .axd 請求都會觸發此事件。一個頁面若引用多個 Script/樣式,就會觸發多次。
  3. Session 尚未建立:對於 .axd 等非頁面請求,ASP.NET 不會建立 Session,導致 Session["token"] 為 null,呼叫 .ToString() 拋出 NullReferenceException,中斷回應串流,造成 AJAX 載入失敗。

解決方案

方案一:判斷 Session 是否為 null(最簡單)

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    if (Session != null && Session["token"] != null)
    {
        string oldToken = Session["token"].ToString();
        // 後續邏輯...
    }
}

方案二:攔截 .axd/.asmx 請求直接返回(推薦,效能較好)

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    HttpApplication app = (HttpApplication)sender;
    HttpContext context = app.Context;

    // 排除 AJAX 資源請求、Web Service 請求
    string url = context.Request.Url.AbsolutePath.ToLower();
    if (url.EndsWith(".axd") || url.EndsWith(".asmx"))
        return;

    // 正常頁面請求才處理 Session
    if (context.Session != null && context.Session["token"] != null)
    {
        string oldToken = context.Session["token"].ToString();
        // 後續邏輯...
    }
}

方案三:改用 PostAcquireRequestState(進階)

若邏輯必須在 Session 確定可用之後執行,可改掛在 Application_PostAcquireRequestState,此時 Session 已確保可用(若啟用 Session)。但仍建議搭配方案二過濾 .axd 請求。

IIS 6 vs IIS 7+ 差異補充

特性 IIS 6 (Classic Mode) IIS 7+ (Integrated Mode)
.axd 請求是否經過 Managed Pipeline是(需 wildcard mapping)否(原生模組處理,不進入 Managed Handler)
Application_AcquireRequestState 觸發次數每個 .axd 請求各觸發一次僅頁面請求觸發
Session 可用性.axd 請求無 Session.axd 請求不進入此事件

最佳實踐總結

  • 在 Global.asax 任何事件中存取 Session 前,務必先判斷 `Context.Session != null`。
  • 針對 .axd、.asmx、.ashx 等特殊副檔名請求,盡早 return,避免不必要的 Session 存取與邏輯執行。
  • 若專案仍需支援 IIS 6,建議在 web.config 設定 <httpModules> 而非 <modules>,並確認 wildcard mapping 正確。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved