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

防止瀏覽器回退按鈕讀取快取:JSP/HTTP 快取控制完整方案

     編輯:關於JSP

問題場景

用戶登出或提交表單後點擊瀏覽器「上一頁」/「回退」按鈕,若頁面被快取,可能顯示過時敏感資料 (如帳號餘額、表單已填資料) 或導致重複提交。需透過 HTTP Header 指示瀏覽器不快取敏感頁面。

方案一:Java 程式碼設定回應 Header (推薦,動態頁面)

在 JSP 頁面最頂端或 Servlet doGet/doPost 開頭加入:

<%
response.setHeader("Pragma", "No-cache");           // HTTP 1.0
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1
response.setDateHeader("Expires", 0);                // 過期時間設為過去
%>
  • Pragma: No-cache:HTTP/1.0 相容。
  • Cache-Control: no-cache, no-store, must-revalidate:HTTP/1.1 標準,no-store 禁止任何快取,must-revalidate 強制向伺服器驗證。
  • Expires: 0 (或負值):告知瀏覽器內容已過期。

方案二:HTML Meta 標籤 (靜態頁面/兼容舊瀏覽器)

<head>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Expires" content="0">
</head>

缺點:Proxy 快取伺服器不解析 HTML Meta,僅對瀏覽器本地快取有效。動態頁面請優先用方案一。

進階:針對特定資源類型的快取策略

資源類型建議 Header說明
登入/登出頁、個人資料、交易確認頁Cache-Control: no-store, private絕對禁止快取,含敏感資訊
列表頁、搜尋結果Cache-Control: private, max-age=60, must-revalidate允許短暫私有快取 (60 秒),降低伺服器壓力
靜態資源 (CSS/JS/圖片/字體)Cache-Control: public, max-age=31536000, immutable長期強快取 (1 年),配合檔名哈希 (如 app.a1b2c3.js) 實現版本更新
API 回應 (JSON)Cache-Control: no-store 或依業務 max-age視資料時效性決定

Spring MVC / Spring Boot 統一配置

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) {
                String path = req.getRequestURI();
                if (path.startsWith("/static/") || path.startsWith("/assets/")) {
                    resp.setHeader("Cache-Control", "public, max-age=31536000, immutable");
                } else {
                    resp.setHeader("Cache-Control", "no-store, private, must-revalidate");
                    resp.setHeader("Pragma", "no-cache");
                    resp.setDateHeader("Expires", 0);
                }
                return true;
            }
        });
    }
}

常見誤區

  • 只設 Cache-Control: no-cache:瀏覽器仍可快取,但每次使用前需向伺服器驗證 (發送 If-None-Match/If-Modified-Since),不等於不快取。必須加 no-store。
  • 在 JSP 中間輸出 HTML 後才設 Header:Header 必須在 任何內容輸出前 設定,否則會拋出 IllegalStateException。
  • 以為 Meta 標籤能控制 CDN/Proxy:只有 HTTP Header 能控制中間節點快取行為。

測試驗證方法

  1. 開啟瀏覽器開發者工具 (F12) → Network 頁籤。
  2. 訪問目標頁面,點選該請求,檢視 Response Headers 是否包含 Cache-Control: no-store 等。
  3. 點擊瀏覽器回退按鈕,觀察 Network 是否發出新請求 (狀態碼 200) 或顯示 (from disk cache) / (from memory cache)。
  4. 使用 curl -I -v https://example.com/page.jsp 檢視原始 Header。

結語

正確的 HTTP 快取控制是 Web 安全與使用者體驗的基石。敏感動態頁面務必設定 Cache-Control: no-store, private, must-revalidate + Pragma: no-cache + Expires: 0,並在架構層面 (Filter/Interceptor) 統一管控,避免開發者遺漏。靜態資源則應積極啟用長期強快取並配合指紋檔名,實現效能與一致性的最佳平衡。

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