用戶登出或提交表單後點擊瀏覽器「上一頁」/「回退」按鈕,若頁面被快取,可能顯示過時敏感資料 (如帳號餘額、表單已填資料) 或導致重複提交。需透過 HTTP 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 (或負值):告知瀏覽器內容已過期。<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 | 視資料時效性決定 |
@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。IllegalStateException。Cache-Control: no-store 等。(from disk cache) / (from memory cache)。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) 統一管控,避免開發者遺漏。靜態資源則應積極啟用長期強快取並配合指紋檔名,實現效能與一致性的最佳平衡。