element-ui如何防⽌重复提交的⽅法步骤
先说对话框(Dialog)⾥的表单提交
错误⽅案
说起错误⽅案,⽐如,点击提交按钮,本地验证,验证通过⽴即让按钮不可点,这些没问题,⽽我的错误点概括是:在某个最后执⾏的回调函数的最后⼀⾏,我做了2个操作:1,隐藏Dialog,2,让提交按钮可点击。
这个⽅案看似没问题,做到了让对话框消失,⼜保证下⼀次打开Dialog之后,提交按钮是可点击的。但它错误在于:隐藏Dialog是⼀个动画过程,并不是瞬间消失,所以按钮恢复可点击之后,Dialog还没有彻底隐藏,所以只要你点得够快,就可以多点⼏次按钮。
正确⽅案
1. 早在打开对话框的时候,将提交按钮可点击。做法是在<el-dialog>上加⼊open事件函数:
@open="submitButtonDisabled = false",其中submitButtonDisabled是我控制提交按钮的变量,你可以改成你⾃⼰⽤的。
发送ajax请求的步骤
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。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。