51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 1864|回复: 0
打印 上一主题 下一主题

Web系统的表单重复提交问题及解决方案

[复制链接]
  • TA的每日心情
    无聊
    昨天 09:02
  • 签到天数: 944 天

    连续签到: 3 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2020-10-13 09:50:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    表单页面JSP:

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>

    2.    <html>

    3.      <head>

    4.        <title>表单页面</title>

    5.      </head>

    6.      <body>

    7.        <form action="commit" method="post">

    8.          <input type="text" name="username" />

    9.          <input type="submit" id="submit"/>

    10.        </form>

    11.      </body>

    12.    </html>


    13.   表单处理Servlet



    14. public class FormServlet extends HttpServlet {

    15.        @Override

    16.        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    17.            try {

    18.                Thread.sleep(2000); // 模拟网络延迟

    19.            } catch (InterruptedException e) {

    20.                e.printStackTrace();

    21.            }

    22.            req.setCharacterEncoding("utf-8");

    23.            System.out.println("对" + req.getParameter("username") + "进行处理");

    24.        }

    25.    }
    复制代码
    用户重复提交的场景
      只列举了常见的场景
      场景一:表单提交后,因为网络延迟,让用户有时间重复点击提交。
      场景二:表单提交后,用户刷新页面,导致表单重复提交。
      场景三:表单提交后,用户退回上一个页面,再次点击提交。
      场景四:在一个浏览器中,用户打开两个标签页进行提交。
      重复提交的解决方案
      2.1 方案一
      在前端,通过设置一个标识变量,标识表单的提交状态。(只能解决场景一)
      标识变量默认为false,一旦表单提交触发,会判断标识变量是否为false,如果为false则发送请求并且将标识变量更改为true,如果为true则不发送请求。

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>

    2.    <html>

    3.      <head>

    4.        <title>表单页面</title>

    5.        <script type="text/javascript">

    6.          var isCommitted = false; // 默认未提交

    7.          function doSubmit() {

    8.            if (isCommitted == false) {

    9.              isCommitted = true; // 改为已提交

    10.              return true;

    11.            }else {

    12.              return false;

    13.            }

    14.          }

    15.        </script>

    16.      </head>

    17.      <body>

    18.        <form action="commit" method="post" onsubmit="return doSubmit()"> <!--通过doSubmit函数,动态地给onsubmit属性赋值-->

    19.          <input type="text" name="username" />

    20.          <input type="submit" id="submit"/>

    21.        </form>

    22.      </body>

    23.    </html>
    复制代码
    2.2 方案二
      在后端,通过session和唯一Token来判断重复提交。(可以解决四个场景)
      服务器通过session为用户保存一个唯一Token,并且给到浏览器,浏览器会将其保存在一个隐藏的域中随表单提交。
      当第一次提交时,提交的Token与session中的Token相等,进行相应处理,并且删除session中的Token。  
      1.TokenProcessor的工具类

    1. public class TokenProcessor {

    2.        private static final TokenProcessor instance = new TokenProcessor();

    3.   

    4.        public static TokenProcessor getInstance() {

    5.            return instance;

    6.        }

    7.        public String makeToken() {

    8.            String token = String.valueOf(System.currentTimeMillis() + new Random().nextInt(999999999));

    9.            try {

    10.                MessageDigest md = MessageDigest.getInstance("md5");

    11.                byte md5[] = md.digest(token.getBytes());

    12.                Base64.Encoder encoder = Base64.getEncoder();

    13.                return encoder.encodeToString(md5);

    14.            } catch (NoSuchAlgorithmException e) {

    15.                e.printStackTrace();

    16.                return null;

    17.            }

    18.        }

    19.    }
    复制代码
     2.获取session和Token的Servlet
    以下为方案二测试结果:
    场景一


    场景二

    场景三

    场景四(只有后进入的表单页面有最新的Token)


    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-5-9 02:21 , Processed in 0.063884 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表