前端如何防止接口数据重复提交

一、什么是接口重复提交?

接口重复提交指的是在网络通信中,同一个请求被客户端多次发送到服务器端的情况。这种情况可能由于多种原因导致,例如用户在等待期间多次点击提交按钮、网络超时后客户端重新发送请求、客户端发送的请求在网络传输过程中出现重复等。

接口重复提交可能会导致多种问题,当服务器收到重复请求时,可能会多次处理相同的数据,导致数据重复操作或者产生不一致的结果。重复提交请求会增加服务器的负载和资源消耗,特别是在高并发情况下,可能会导致服务器压力过大,影响系统的性能和稳定性。有些请求是具有副作用的,例如支付、提交订单等,重复提交可能导致用户被重复扣款或者重复生成订单,从而导致业务异常或者用户不满。

二、如何防止?

1.禁用或隐藏提交按钮,显示加载状态

在用户点击提交按钮后,立即禁用该按钮,防止用户多次点击。可以在接口请求结束后重新启用按钮。代码如下所示。

<form id="myForm">
  <!-- 表单内容 -->
  <button type="submit" id="subBtn">提交</button>
  <div id="loading" style="display: none;">正在加载...</div>
</form>

<script>
document.getElementById('myForm').addEventListener('submit', function(event) {
  event.preventDefault(); // 阻止默认提交行为
  document.getElementById('subBtn').disabled = true; // 禁用提交按钮
  //document.getElementById('subBtn').style.display = 'none'; // 隐藏提交按钮
  document.getElementById('loading').style.display = 'block'; // 显示加载状态
  // 发送请求
  fetch('/api/submit', {
    method: 'POST',
    // 请求参数
  }).then(function(response) {
    // 处理响应
    document.getElementById('subBtn').disabled = false; // 启用提交按钮
    //document.getElementById('subBtn').style.display = 'block'; // 显示提交按钮
    document.getElementById('loading').style.display = 'none'; // 隐藏加载状态
  }).catch(function(error) {
    console.error('Error:', error);
    document.getElementById('subBtn').disabled = false; // 启用提交按钮(如果请求失败)
    //document.getElementById('subBtn').style.display = 'block'; // 显示提交按钮
    document.getElementById('loading').style.display = 'none'; // 隐藏加载状态
  });
});
</script>

2.设置按钮防抖或节流

// 防抖函数
function sleepTime(func, delay) {
  let timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(func, delay);
  };
}

document.getElementById('subBtn').addEventListener('click', sleepTime(function() {
  // 发送请求
  fetch('/api/submit', {
    method: 'POST',
    // 请求参数
  }).then(function(response) {
    // 处理响应
  }).catch(function(error) {
    console.error('Error:', error);
  });
}, 1000)); // 1秒内只允许点击一次

3.前端生成请求标识符

// 生成唯一标识符
function generateRequestId() {
  return Math.random().toString(36).substr(2, 9);
}
let requestId;
document.getElementById('subBtn').addEventListener('click', function() {
  requestId = generateRequestId(); // 生成请求标识符
  // 发送请求
  fetch('/api/submit', {
    method: 'POST',
    headers: {
      'X-Request-Id': requestId // 将请求标识符添加到请求头中
    },
    // 请求参数
  }).then(function(response) {
    // 处理响应
  }).catch(function(error) {
    console.error('Error:', error);
  });
});

4.通过使用Store状态管理库

import store from './store'; // 引入状态管理库

document.getElementById('subBtn').addEventListener('click', function() {
  if (store.state.isSubmitting) {
    return; // 如果正在提交,则不执行后续操作
  }
  // 设置提交状态
  store.commit('setSubmitting', true);
  // 发送请求
  fetch('/api/submit', {
    method: 'POST',
    // 请求参数
  }).then(function(response) {
    // 处理响应
    store.commit('setSubmitting', false); // 恢复非提交状态
  }).catch(function(error) {
    console.error('Error:', error);
    store.commit('setSubmitting', false); // 恢复非提交状态(如果请求失败)
  });
});

5.通过变量状态进行接口锁定

let isReq = false;
document.getElementById('submitButton').addEventListener('click', function() {
  if (isReq) {
    return; // 如果正在请求,则不执行后续操作
  }
  isReq= true; // 锁定接口
  // 发送请求
  fetch('/api/submit', {
    method: 'POST',
    // 请求参数
  }).then(function(response) {
    // 处理响应
    isReq= false; // 解锁接口
  }).catch(function(error) {
    console.error('Error:', error);
    isReq= false; // 解锁接口(如果请求失败)
  });
});

三、总结

防止接口重复提交是为了确保系统的数据一致性、避免不必要的资源浪费和提升用户体验。为了避免接口重复提交带来的问题,需要在前端和后端都进行相应的处理,例如在前端禁用提交按钮、显示加载状态,在后端实现幂等性检查等。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小码夫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值