問題現象
開發者常遇到這樣的場景:
$.ajaxSetup({beforeSend: () => console.log("? 觸發"), // 正常執行error: () => console.log("? 未觸發"), // 靜默失效complete: () => console.log("? 未觸發") // 同樣沉默
});
四大核心原因
-
同步請求封鎖
async: false
會導致瀏覽器線程阻塞,使異步回調無法執行 -
配置覆蓋戰爭
多次調用$.ajaxSetup()
會產生配置覆蓋(后者覆蓋前者) -
跨域隱形攔截
未正確配置CORS時,瀏覽器會靜默丟棄響應 -
執行順序陷阱
攔截代碼未在首個AJAX請求前加載
六步終極解決方案
1. 強制異步模式
$.ajax({ async: true, // 必須顯式聲明// ...其他參數
});
2. 事件委托方案(推薦)
$(document).ajaxSend(() => console.log("🌐 全局beforeSend")).ajaxError(() => console.log("💥 全局error")) .ajaxComplete(() => console.log("🎯 全局complete"));
3. 跨域配置模板
# 服務器響應頭必須包含
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,OPTIONS
Access-Control-Allow-Headers: Content-Type
4. 錯誤增強處理
error: (xhr) => {if(xhr.status === 0) alert("網絡斷開/CORS攔截");if(xhr.status === 401) location.href = '/login';
}
5. 防御式編程
// 防止第三方庫覆蓋
const originalAjax = $.ajax;
$.ajax = function() {console.log("🛡? 請求攔截");return originalAjax.apply(this, arguments);
};
6. 現代替代方案
// 使用fetch API + AbortController
const controller = new AbortController();
fetch(url, { signal: controller.signal
}).catch(e => {if(e.name === 'AbortError') console.log("請求被取消");
});
最佳實踐清單
-
? 永遠使用
$(document).ajaxSend
替代$.ajaxSetup
-
? 在
$(document).ready()
中初始化攔截器 -
? 為關鍵請求添加超時控制
-
? 在Node.js測試環境驗證攔截邏輯