如何处理 api 重复提交,接口幂等性 8种方案解决重复提交问题

   表单重复提交请求:

由于重复点击或者网络重发 
1)点击提交按钮两次;
2)点击刷新按钮;
3)使用浏览器后退按钮重复之前的操作,导致重复提交表单; 4)使用浏览器历史记录重复提交表单; 5)浏览器重复的HTTP请; 6)nginx重发等情况; 7)分布式RPC的try重发等; 作者:锦成同学 链接:https://juejin.im/post/5d31928c51882564c966a71c 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  创建一个 Dynamic Web Project 演示

   FormServlet

View Code

  index.jsp

View Code

  访问 http://localhost:8080/form-repeat-demo/,因为请求的延迟,快速点击按钮,会导致重复提交。

1、前端表单提交后通过 js 禁止按钮点击

<form action="${pageContext.request.contextPath}/FormServlet" method="post">
    <input type="text" name="name" /><br/>
    <input type="button" value="提交" onclick="handleSubmit(this)" />
</form>
<script type="text/javascript">
    function handleSubmit(buttonObj) {
        document.forms[0].submit();
        buttonObj.disabled = true;
    }
</script>

  点击按钮后,按钮变暗,不能继续点击;浏览器跳转到 http://localhost:8080/form-repeat-demo/FormServlet

   但是 F5 刷新或者后退,仍然可以重复提交表单。所以,这种方法并不能完全解决。

2、token 令牌机制(表单令牌与服务器保存的令牌比对)

  token 令牌机制:表单提交时发送一个 token,这个 token 之前已经保存在 服务器,当处理一次请求后删除 服务器中 token,保证只处理一次表单提交请求。

  这里演示服务器令牌保存在 session。

  修改 index.jsp:

View Code

  FormServlet 中判断表单提交 的 token 和 session 中的 token

View Code

  这样,点击提交按钮后,发送请求,浏览器地址变为提交表单的地址 http://localhost:8080/form-repeat-demo/FormServlet。F5 刷新页面和回退页面继续点击提交按钮,都会提示重复提交信息。

  这样,表单就只能提交一次。如果想要继续提交,需要刷新页面,重写生成页面更新 token。

  上面的演示,显然需要使用到动态页面技术(获取到的页面是动态页面,需要往 session 中添加 token)。

  前后端分离架构中,前端都是静态页面,数据提交时要向服务申请 token(或前后端使用同一规则),token 放到redis 或 内存。提交后同时删除 token。

  token 生成可以参考 本文最后链接 1 和 3。

3、nonce 机制 + 表单校验

  nonce 机制:每一次请求过来 nonce 加一;后端保存前一次请求的 nonce,校验每次请求的 nonce。如果nonce 不大于保存的 nonce,则认为是重复请求。这其实也是防重放攻击的一种处理。HTTP 中摘要(Digest )认证就是采用这种机制。

  另外为了保证每次请求都是用户希望的请求,表单输入可以做非空校验等,点击提交按钮后清空输入。这样用户重复点击,也通不过校验。

4、借助数据库

  insert 使用唯一索引, update使用乐观锁 version版本法 这种在大数据量和高并发下效率依赖数据库硬件能力,可针对非核心业务

参考:

  1)API接口幂等设计(Token方式防止表单重复提交或网络延迟)

  2) 8种方案解决重复提交问题

  3)spring boot 通过AOP防止API重复请求

  4)如何防止接口重复请求

  5)SpringBoot利用AOP防止请求重复提交

  6) https://www.jianshu.com/p/364a6f466a2a

  7) https://cloud.tencent.com/developer/article/1460588
---

猜你喜欢

转载自www.cnblogs.com/xy-ouyang/p/12748070.html