前端防重复提交(第一道防线)实战方案

在日常开发中,重复提交问题是一个常见但容易被忽视的技术痛点。

当用户在Web页面或移动端进行数据提交操作时,可能会因为以下典型场景导致重复提交:

1.用户快速点击按钮导致多次提交同一表单

2.网络延迟接口响应延迟时,用户反复重试提交

3.用户误点导致连续触发提交事件

4.页面卡顿时,用户反复刷新或返回重试

这种重复提交问题带来的影响:

1.降低用户体验

2.导致数据库产生重复记录,数据异常,统计指标不准确

3.可能导致重复下单、重复支付等资金风险

4.造成不必要的资源消耗,影响系统的性能。

我们需要建立完整的防重体系,本文将总结一下前端防止重复提交的主流解决方案。

核心原则:前端可防误操作,但后端才是最终防线

前端方案不能替代后端校验,但能提升用户体验。是第一道防线,一定要做的,不容忽视。

一、按钮禁用disabled

提交后立即禁用按钮,防止用户连续点击。友好提示。

<button id="submitBtnId" onclick="submitForm()">提交</button>
function submitForm() {
    const btn = document.getElementById("submitBtnId");
    if (btn.disabled) return;
   
    btn.disabled = true;
    btn.innerText = "提交中...";

    // 发送请求
    fetch("/submit", {
        method: "POST"
    }).then(res => {
        // 提交成功
    }).finally(() => {
        btn.disabled = false;
        btn.innerText = "提交";
    });
}

二、按钮防抖(Debounce)

function debounce(func, wait) {
  let timeout;
  return function () {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(this, arguments);
    }, wait);
  };
}

// 使用示例
const submitForm = debounce(function() {
  // 提交逻辑
}, 1000);

三、请求拦截

const pendingRequests = new Map();

axios.interceptors.request.use(config => {
  const requestKey = `${config.url}/${JSON.stringify(config.data)}`;
  if (pendingRequests.has(requestKey)) {
    return Promise.reject(new Error('请勿重复提交'));
  }
  pendingRequests.set(requestKey, true);
  return config;
});

axios.interceptors.response.use(response => {
  const requestKey = `${response.config.url}/${JSON.stringify(response.config.data)}`;
  pendingRequests.delete(requestKey);
  return response;
});

前端方案优点:

用户体验好,防止手滑,重复提交

缺点:

可能被绕过,如F12控制台修改JS、Postman重放请求。

前后端结合,前端做好第一道防线,防止重复点击提升用户体验感,后端一定要做好最终的防线。

最佳实践建议

前后端结合:前端防“误点”,后端防“重放”

合理设置过期时间:5~10秒足够,避免影响正常操作

日志记录:对重复提交行为打日志,便于排查

友好提示:不要返回500,应提示“请勿重复提交”

防止重复提交是保障系统稳定性和数据一致性的关键能力。我们不能仅依赖用户操作规范,而需要通过技术手段构建多层次的防御机制。

根据具体业务需求选择合适的解决方案,必要时可组合使用多种方法,确保万无一失。

希望本文能为您提供帮助。如有任何疑问或建议,欢迎在评论区交流讨论~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值