經典 ASP (VBScript) 頁面 `zf.asp`:點擊鏈接跳轉執行插入邏輯,**每次點擊插入兩條相同記錄**;刷新頁面 (F5) 僅插入一條。
| 方案 | 原理 | 實現難度 | 適用性 |
|---|---|---|---|
| PRG 模式 (Post-Redirect-Get) - 最佳 | 鏈接改為 POST 表單提交 → 後端處理完**重定向 (302)** 到結果頁 → 瀏覽器不會預取 POST,刷新也不重複提交 | 中 (需改鏈接為表單) | 所有 Web 應用通用最佳實踐 |
| 冪等性 Token (一次性令牌) | 生成唯一 Token 存 Session/DB → 頁面隱藏域帶上 → 處理前驗證 Token 有效性 → 標記已用/刪除 → 重複請求自動拒絕 | 中 | 無法改 POST 時的備選 |
| 檢查請求頭拒絕預取 | `If Request.ServerVariables("HTTP_SEC_PURPOSE") = "prefetch" Then Response.End` | 低 | 依賴瀏覽器發送標準頭,非標準行為可能漏網 |
| GET 改為 POST + JavaScript 提交 | 鏈接點擊觸發 JS `form.submit()`,非直接導航 | 低 | 需 JS 啟用,預取通常不執行 JS |
| 業務層去重 (唯一約束) | DB 表加唯一索引 (`user_id`, `content`, `create_time` 組合) → 插入捕獲重複鍵錯誤忽略 | 低 | 治標不治本,但作為最後防線必須有 |
<%
' 1. 驗證參數、權限
' 2. 執行插入/更新業務邏輯
' 3. 重定向回列表頁 (或結果頁)
Response.Redirect "list.asp?msg=success"
%>
最佳回答核心:「打開浏覽器開發工具監測 轉發的這個頁面是否有別的請求操作。」—— 直接指向 Network 面板驗證雙重請求假設,排查思路清晰。