發起相同 URL 的 GET 請求(如 demo_get.asp),瀏覽器可能直接返回緩存的響應,而不向服務器發起真實請求,導致數據不更新。
HTTP 緩存機制:瀏覽器根據 URL 作為鍵 存儲響應。同一 URL 再次請求時,若緩存未過期(無 Cache-Control: no-cache 或 Expires 過期),直接讀取緩存,不發網絡請求。
xmlhttp.open("GET", "demo_get.asp?t=" + Math.random(), true);
xmlhttp.send();
原理:Math.random() 生成隨機數,使每次請求 URL 唯一(如 demo_get.asp?t=0.123456、demo_get.asp?t=0.789012),瀏覽器視為不同資源,繞過緩存,強制向服務器發請求。
xmlhttp.open("GET", "demo_get.asp?_=" + Date.now(), true);
// jQuery
$.ajax({
url: 'demo_get.asp',
cache: false, // 內部自動加 _=timestamp 參數
success: fn
});
// Axios
axios.get('demo_get.asp', { headers: { 'Cache-Control': 'no-cache' } });
// Fetch API
fetch('demo_get.asp', { cache: 'no-store' });
// PHP
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
// Java Servlet
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
// Nginx
add_header Cache-Control "no-cache, no-store, must-revalidate";
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 隨機參數/時間戳 | 無需改動服務端,兼容所有環境 | URL 變長,日誌難分析,CDN 可能不緩存 | 快速修復、第三方 API 無法控制響應頭 |
| 客戶端請求頭 | 代碼清晰,框架內置支持 | 舊瀏覽器/代理可能忽略 | 現代前端框架項目 |
| 服務端響應頭 | 徹底、規範、CDN 也可遵守 | 需後端配合,靜態資源可能誤傷 | 動態 API、用戶數據接口(最佳實踐) |
ETag/Last-Modified 配合 If-None-Match/If-Modified-Since 實現「有更新才傳輸」,比禁用緩存更高效。