$("form").on("submit", function() {
$(this).find("input[type=submit]").prop("disabled", true); // 錯誤!表單尚未提交,按鈕已禁用 → 瀏覽器取消提交
return true;
});
原因: HTML 表單提交機制要求提交按鈕在提交瞬間處於**啟用狀態**。JS 設定 `disabled=true` 會立即生效,導致瀏覽器認為「無有效提交按鈕」而中止提交。
var submitting = false; // 模組級旗標
$("form").on("submit", function(e) {
if (submitting) {
e.preventDefault(); // 阻止瀏覽器預設提交
return false;
}
submitting = true;
// 可選:UI 反饋
var $btn = $(this).find("input[type=submit], button[type=submit]");
$btn.prop("disabled", true).val("提交中...");
// 表單正常提交 (非 AJAX),頁面將跳轉/重載,旗標隨頁面釋放
// 若為 AJAX 提交,需在 complete/error 回調中重置 submitting = false
});
$("form").on("submit", function(e) {
e.preventDefault(); // 1. 先阻止預設提交,完全由 JS 控制
var $form = $(this), $btn = $form.find(":submit");
if ($btn.prop("disabled")) return; // 2. 雙重防禦
$btn.prop("disabled", true).data("orig-text", $btn.val()).val("提交中...");
$.ajax({
url: $form.attr("action"),
type: $form.attr("method") || "POST",
data: $form.serialize(),
success: function(resp) {
// 成功處理...
},
error: function() {
// 錯誤處理...
},
complete: function() {
// 3. 无论成败,恢复按钮
$btn.prop("disabled", false).val($btn.data("orig-text") || "提交");
}
});
});
瀏覽器原生驗證 (`required`, `pattern`, `type="email"`) 發生在 `submit` 事件**之前**。若驗證失敗,`submit` 事件不會觸發,旗標也不會被設定,**完全相容**,無需額外處理。
「設置個變量,當這個變量為0時就讓它提交同時這個變量加1;然後在提交事件裡寫個if判斷當這個變量不為零時讓這個按鈕不能被點擊然後返回false」
即 **旗標變數 + 事件攔截** 模式,為經典且有效的防重方案。
前端旗標 + 後端冪等 = 完整的重複提交防禦體系。