如何防止页面重复提交

思路:

重复提交有两方面的含义,

一是操作方面的重复提交,旨在说明一个客户端,一次只能发送一个请求到服务端,如果发出后未收到服务端响应,再次提交,则视为无效提交(重复了)。

二是业务方面,同一个表单,服务端处理了两次,两次都是合法的操作(不违反第一种含义),但是表单可能被处理了两次,如像一个账号转账了两次,金额信息一致,可能后台的交易流水不一致,但是确实产生了两笔交易。

在web项目中,防止重复提交,需要解决以上两种问题,

第一种的解决思路是通过token的思路。

第二种通过业务判断解决

以下部分代码,首先服务端

表单提交前,或者表单加载时,服务端返回客户端token 

Session["LAST_TOKEN"] = token;

服务端接收客户端发来的token,同时产生并、注册、返回新的token 以便下次请求使用

            string token = Guid.NewGuid().ToString();

            if (Session["LAST_TOKEN"] == null || Session["LAST_TOKEN"].ToString() != submitToken)
            {
                Session["LAST_TOKEN"] = token;
                return Json(new
                {
                    isSuccess = false,
                    message = "提交失败,可能是以下原因导致的:<br/> 1.点击频繁或按键失灵。<br/>2.页面长时间未操作。<br/><font color=\"red\">如已出票,请忽略此消息!未出票,请重试!</font>",
                    code = 510,
                    token
                });
            }
            Session["LAST_TOKEN"] = token;

以上方式,可解决问题一

 

下面的方式,解决问题二

            Result<string> verfiyResult = this.FilterDuplicateOrderSubmit(bill, VerificationCode);
            if (!verfiyResult.Success)
            {
                return Json(new
                {
                    isSuccess = false,
                    message = verfiyResult.Message,
                    code = 520,
                    VerificationCode = verfiyResult.Entity,
                    token
                });
            }

服务端检测到重复 ,返回520错误码,同时包含验证码,要求客户端下次请求附加此验证码,才能通过验证

private Result<string> FilterDuplicateOrderSubmit(BillNew bill, string VerificationCode)
        {if (string.IsNullOrWhiteSpace(bill.Consignee) || string.IsNullOrWhiteSpace(bill.Shipper) || bill.EndDepartId == 0) {
                return new Result<string>("缺少必要校验信息,不在校验,让业务规则校验", true);
            }
            var lastOrderInfo = bill.Consignee + bill.ConsigneePhone + bill.Shipper + bill.ShipperPhone ;if (Session["LAST_ORDER_INFO"] != null && Session["LAST_ORDER_INFO"].ToString() == lastOrderInfo)
            {
                var code = RandomString.GetRndStrFor(3, false, false, true);
                if (Session["LAST_ORDER_INFO_VerificationCode"] == null)
                {
                    Session["LAST_ORDER_INFO_VerificationCode"] = code;
                    return new Result<string>("<font color=\"red\">本次提交信息与上次提交相似,可能造成重复,请务必核对确认。</font><br/>如确认无误,请在页面右下方输入正确验证码后提交。", false, code);
                }
                else
                {
                    if (Session["LAST_ORDER_INFO_VerificationCode"].ToString() != VerificationCode)
                    {
                        Session["LAST_ORDER_INFO_VerificationCode"] = code;
                        return new Result<string>("输入的验证码不正确,请在页面右下方输入正确验证码后提交。<br/><font color=\"red\">本次提交信息与上次提交相似,可能造成重复,请务必核对确认。</font>", false, code);
                    }
                    else
                    {
                        Session["LAST_ORDER_INFO"] = lastOrderInfo;
                        Session["LAST_ORDER_INFO_VerificationCode"] = null;
                        return new Result<string>("校验通过", true);
                    }
                }
            }
            Session["LAST_ORDER_INFO"] = lastOrderInfo;
            return new Result<string>("无重复!", true);
        }
posted @ 2020-01-18 10:51  超级飞猪猪侠  阅读(1577)  评论(0编辑  收藏  举报