element-ui如何防止重复提交的方法步骤

 更新时间:2019年12月09日 15:21:44   作者:microkof  
这篇文章主要介绍了element-ui如何防止重复提交的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

先说对话框(Dialog)里的表单提交

错误方案

说起错误方案,比如,点击提交按钮,本地验证,验证通过立即让按钮不可点,这些没问题,而我的错误点概括是:在某个最后执行的回调函数的最后一行,我做了2个操作:1,隐藏Dialog,2,让提交按钮可点击。

这个方案看似没问题,做到了让对话框消失,又保证下一次打开Dialog之后,提交按钮是可点击的。但它错误在于:隐藏Dialog是一个动画过程,并不是瞬间消失,所以按钮恢复可点击之后,Dialog还没有彻底隐藏,所以只要你点得够快,就可以多点几次按钮。

正确方案

  1. 早在打开对话框的时候,将提交按钮可点击。做法是在<el-dialog>上加入open事件函数:@open="submitButtonDisabled = false",其中submitButtonDisabled是我控制提交按钮的变量,你可以改成你自己用的。
  2. 点击之后验证,通过则立即按钮不可点(this.submitButtonDisabled = true),不通过则不做任何针对按钮的处理。(这是铁律,下面会经常看到)
  3. 验证通过的话,最后执行的某个回调函数的最后一行,隐藏对话框。比如this.dialogFormVisible = false,这个变量你也要改成自己用的。

它的核心是2点:早在打开对话框的时候就让提交按钮可点击;验证通过的话,最后的回调函数不应该去管提交按钮恢复可点击的事,而是放到下一次打开对话框的时候才让提交按钮可点击。

再说不涉及对话框的提交

不涉及对话框,比如按钮在页面上直接存在,又分三种情况:

  1. 点击之后不跳转,但按钮消失
  2. 点击之后不跳转,按钮也不消失
  3. 点击之后跳转页面

即便是跳转页面,也是需要时间的,这个期间一样可以重复提交。不跳转页面的话,重复提交就更容易发生了。怎么办?

情况1:点击之后不跳转,但按钮消失

这种情况出现在小型提交场合,比如在表格中修改数据,表格中的某个单元格有一个修改按钮,点击之后按钮消失,只留下数据自己,而且,不允许有成功提示框,因为毕竟是小型提交场合,而且提交按钮消失就已经代表了成功。

这就是三种不同的状态,依次是无数据时、编辑状态时、有数据时

这种情况的处理方案很简单:

  1. 点击之后验证,通过则立即不可点,不通过则不针对按钮处理
  2. 服务器返回结果之后,保存成功则按钮消失,保存失败则按钮依旧存在。无论成功失败,按钮都要变成可点击。由于这里按钮消失是瞬间发生,没有动画过程,所以就算按钮变回可点击,也因为它已经消失,因此不会造成重复提交。

这里引出一个问题,就是表格中的小型提交场合,Save按钮会有一竖列,如何准确给某个按钮设置不可点击呢?可以这样:

  1. 从服务器获取表格数据之后要做一步加工,遍历数据,加上item.saveButtonDisabled = false之类的语句,然后再赋值给data子对象。
  2. 给按钮绑定方法时,要传参数,element-ui中可以传row,也就是@click="clickSave(row)"。
  3. 点击按钮先验证数据,通过则立即row.saveButtonDisabled = true,ajax回调之后就row.saveButtonDisabled = false,就可以了。

情况2:点击之后不跳转,按钮也不消失

比如一个表单直接显示在网页中,无论提交多少次,页面都纹丝不动。

这时候再按照上面的情况的处理方案就行不通了,因为比如1秒数据就走了一个来回,那么我每1.1秒点击一次鼠标就可以无限提交下去。

处理方案:

首先,应该避免做这种“无论提交多少次,页面都纹丝不动”的设定,应该做到ajax返回OK之前,提交按钮是失效的,OK了就让提交按钮可点击,并且要弹个提示框,这个提示框就可以阻断连续提交。这里面还是有一个问题就是,如果在返回OK之后、提示框使用了Dialog,那么弹出的过程中点击了提交按钮,依然是可以提交的,因为还是那个动画问题,提示框弹出是需要时间的。这时候也好办,别用Dialog,用MessageBox就可以了,它有回调函数,在回调函数里让提交按钮可点击,就行了。

然后,如果有些场景下,必须“页面纹丝不动”,提示框都不允许有,那么这时候可以采用节流机制,也就是说按钮点击之后3秒内就不允许再点击,即便上一次的提交已经1秒完成。方案是:

点击之后验证,通过则立即不可点,不通过则不针对按钮处理

通过之后,设个变量resolve = 0,同时执行ajax以及setInterval(fn, 1000),由fn负责判断:

  1. 当ajax返回OK,则resolve += 1
  2. 当ajax返回错误,则resolve += 2
  3. 当延迟3秒,则resolve += 1
  4. 当resolve >= 2则让按钮可点,且clearInterval

这是一种比较奇葩的算法,也就是说,OK和3秒同时具备的话,resolve为2,则让按钮可点,只错误的话,resolve会等于或大于2,就立即让按钮可点,同时报错。

如果ajax超时,比如断网了,那么也会返回错误,只不过这个错误可能会10秒/20秒/30秒/60秒之后返回(根据你的ajax配置),其实这也属于上面说的ajax返回错误,所以依然是适用的。

情况3:点击之后跳转页面

点击之后跳转页面也很常见,无奈跳转页面也是需要时间的,也可以多次提交。怎么办?

  1. 页面打开时,让按钮可点(跟对话框场景道理一样)
  2. 点击之后验证,通过则立即不可点,不通过则不针对按钮处理
  3. 通过之后,当ajax返回OK,则立即跳转(不去恢复成可点),这样鼠标重复点击多少次都没事。当ajax返回错误,则弹出错误,且按钮恢复为可点

为什么当ajax返回错误后不防范重复点击?

因为我们将普通用户定义为:非常喜欢点击鼠标,但思维正常的人,既然用户已经看到了提示错误,当然就不会再重复点击了,况且错误提示往往会是MessageBox,它会阻止重复提交。我们更多的是考虑如何防范鼠标连击的情况。

恶意重复提交

前端永远是防君子,难防小人的,恶意攻击者想要恶意重复提交的话,一定会直接攻击后端,所以上面所有措施一律无效,还需要后端做措施,这里就不多说了。

最后说说axios拦截提交

根据网上一些教程,axios拦截提交其实是有问题的:

  • 它的拦截,其实是在重复提交的时候拦截前一次的提交,而我们通常认为,应该拦截后面发生的所有提交。
  • ajax速度有时候非常快,根本来不及拦截。
  • api写的太晦涩了。
  • 需要考虑多种情况,比如有的时候允许3秒提交一次,有的时候随时可以提交,拦截规则越搞越复杂。

利用URL和params特征判断是否能解决问题

比如,规定时间内(比如3秒),或者不设规定时间,只要向同一个URL发送同样的数据,就禁止发送。表面上看起来,似乎防范重复提交的本质就是要阻止同样的数据重复发送,但是这里面依然有问题。

比如规定时间3秒内不能发送同样数据,那么,如果是axios全局做判断,就要考虑,会不会有其他的ajax穿插在3秒里面,所以说,每次准备ajax发送请求,就要遍历追溯前三秒发送过的请求里有没有重复请求,所以始终要记录每一次请求,还要记下时间戳,似乎有些麻烦。如果只是根据每个提交事件做统计,其实道理一样,也是要遍历。

而且,如果用户每隔4秒点击一次,而ajax返回用时5秒,那么第二次请求就真的会发出去。

如果不规定时间,只要发送同样数据就一定拒绝,那么,如果用户不经意间,在3分钟内2次提交了相同的内容,允许不允许提交呢?比如用户3分钟中了2次奖,填了2次个人信息,允许提交吗?按说应该允许,因为有些场合确实可能存在用户提交同样内容,但是,现在禁止提交,就阻截了正常提交。最后只能是把拦截规则越搞越复杂。

当然,最为致命的问题是:用户体验莫名其妙。无论什么技术,都要把用户体验放在第一位,如果开发者不去管按钮能否点击,只做背后的拦截逻辑,也就是始终让按钮能点击,用户毫无疑问会有很大概率多次点击,如果赶上ajax慢,用户会疯狂点击,最后疯掉也不夸张,这不是我们想要的结果。

所以说前端拦截重复提交的最好办法一定是用正确逻辑控制按钮的disabled。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Vue scoped及deep使用方法解析

    Vue scoped及deep使用方法解析

    这篇文章主要介绍了Vue scoped及deep使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • vue中的scope使用详解

    vue中的scope使用详解

    这篇文章主要介绍了vue中的scope使用详解,需要的朋友可以参考下
    2017-10-10
  • 解决vue中无法动态修改jqgrid组件 url地址的问题

    解决vue中无法动态修改jqgrid组件 url地址的问题

    下面小编就为大家分享一篇解决vue中无法动态修改jqgrid组件 url地址的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue+axios实现post文件下载

    vue+axios实现post文件下载

    这篇文章主要为大家详细介绍了vue+axios实现post文件下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • 详解vue之自行实现派发与广播(dispatch与broadcast)

    详解vue之自行实现派发与广播(dispatch与broadcast)

    这篇文章主要介绍了详解vue之自行实现派发与广播(dispatch与broadcast),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 使用element组件table表格实现某条件下复选框无法勾选

    使用element组件table表格实现某条件下复选框无法勾选

    这篇文章主要介绍了使用element组件table表格实现某条件下复选框无法勾选问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • vue实现可改变购物数量的购物车

    vue实现可改变购物数量的购物车

    这篇文章主要为大家详细介绍了vue实现可改变购物数量的购物车,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Vue 使用中的小技巧

    Vue 使用中的小技巧

    这篇文章主要介绍了Vue 使用中的小技巧,是小编日常开发的时候用到的小技巧,需要的朋友可以参考下
    2018-04-04
  • 在Vue3中使用Vue Tour实现页面导览

    在Vue3中使用Vue Tour实现页面导览

    Vue Tour 是一个方便的 Vue.js 插件,它可以帮助我们在网站或应用中实现简单而灵活的页面导览功能,本文我们将介绍如何在 Vue 3 中使用 Vue Tour,并通过示例代码演示其基本用法,需要的朋友可以参考下
    2024-04-04
  • Vue组件高级通讯之$children与$parent

    Vue组件高级通讯之$children与$parent

    这篇文章主要为大家介绍了Vue组件高级通讯之$children与$parent,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06

最新评论