zoukankan      html  css  js  c++  java
  • 如何处理 api 重复提交,接口幂等性

       表单重复提交请求:

    由于重复点击或者网络重发 
    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
    ---

  • 相关阅读:
    zbb20171108 一台电脑启动多个 tomcat
    zbb20171101 oracle 启动 linux
    zbb20171017 svn Cleanup failed to process the following paths错误的解决
    zbb20171013 mysql服务重启 重启服务 重启mysql服务
    zbb20171013 mysql 远程连接 报错 1130-host ... is not allowed to connect to this MySql server
    zbb20171013 svnserver 修改默认端口
    zbb20171013 tomcat 设置访问ip地址直接访问项目
    zbb20171013 Windows 下端口占用 查询 以及结束进程的方法
    20171012 nginx 超时时间配置
    20171012 tomcat 超时时间配置
  • 原文地址:https://www.cnblogs.com/xy-ouyang/p/12748070.html
Copyright © 2011-2022 走看看