监听表单的 submit 事件,在发送请求前同步设置提交中的标记,再在 finally 中恢复。这样鼠标点击和回车触发的提交都会经过同一个入口。

给提交状态准备一个统一入口
保存为 demo.html,继续把下方脚本加到表单后面。
<form id="demo">
<label>名称 <input name="name" required></label>
<button type="submit">提交</button>
<output aria-live="polite"></output>
</form>
监听表单可以覆盖正常的键盘和按钮提交。
立即学习“Java免费学习笔记(深入)”;
用同步标记阻止第二次请求
示例用本地延迟模拟请求,方便观察提交中状态。
<script>
const form = document.querySelector("#demo");
const button = form.querySelector("button");
const output = form.querySelector("output");
let pending = false;
async function send(data) {
await new Promise(resolve => setTimeout(resolve, 600));
return String(data.get("name"));
}
form.addEventListener("submit", async event => {
event.preventDefault();
if (pending) return;
pending = true;
button.disabled = true;
output.textContent = "提交中";
try {
const name = await send(new FormData(form));
output.textContent = "已提交:" + name;
} catch {
output.textContent = "提交失败,可重试";
} finally {
pending = false;
button.disabled = false;
}
});
</script>标记在第一个 await 前设置。请求成功或失败都会恢复按钮。
用两次快速提交核对结果
填入名称后,在浏览器控制台连续触发两次提交。
document.querySelector("#demo").requestSubmit();
document.querySelector("#demo").requestSubmit();应只进入一次 send。涉及订单等写入时,服务端还应根据业务设计幂等约束,以覆盖跨标签页和重试。


















