再是用ajax提交表单的时候,经常出现重复提交,有通过token的,有提交后跳转页面的。想了解一下现在都有什么方法可以做这个?
认证0级讲师
ajax 防止重复提交处理:
客户端: 1. disabled 提交按钮 2. 定义个变量 var hasSubmit = false,来处理。
服务端: .....................
请搜索 CSRF
你点击按钮的时候,给这个按钮加上一个class,比如ub-click-able,如果有这个class,点击这个按钮不触发Ajax事件。当Ajax处理返回之后,你去掉这个class。
class
ub-click-able
Ajax
提交后加 disabled 属性。
var loginwrap = parent, btn = self, nameInput = loginwrap.find('input[name=name]'), pwdInput = loginwrap.find('input[name=pwd]'), nameError = nameInput.siblings('.errorMsg'), pwdError = pwdInput.siblings('.errorMsg'), name = nameInput.val(), pwd = pwdInput.val(); $.ajax({ type: 'POST', url: url, timeout: 3000, data: { name: name, pwd: pwd }, beforeSend: function () { nameError.text(''); pwdError.text(''); var checkname = yousi_tool.checkReg('phone', name), checkpwd = yousi_tool.checkReg('password', pwd); if (checkname !== true) { //手机号检测有误 nameError.text(checkname); return false; } if (checkpwd !== true) { //密码检测有误 pwdError.text(checkpwd); return false; } btn.text('登录中').attr('disabled', 'disabled'); }, success: function (data) { if (data.code == 200) { } else { pwdError.text(data.desc); } btn.text('登录').removeAttr('disabled'); }, error: function () { btn.text('登录').removeAttr('disabled'); pwdInput.siblings('.errorMsg').text('网络请求有误,请检查网络后再次登录'); } })
这是个大问题,服务器端最好还是要有检查策略,一般关键性的,容易重复提交的request会通过一些参数来保证是合法客户端合法用户的合理请求,像淘宝前端是采集你的各种操作、当前时间、随机码等等来拼成一个token,后端有对应算法来验证这个,保证你没法重复提交。
重复提交一般针对post请求,我的处理方法是这样:维护一个请求队列,每次post请求过来,生成一个包含url,data,timestamp的对象,push到队列中,后续每来一个post请求都对比一下,看请求队列中是否有url相同并且data相同的请求,如果有则认为是重复请求,当前请求丢弃掉。然后再遍历一下请求队列,比较每一个请求对象的timestamp和当前的timestamp,看请求是否超时,超时的话就将请求从队列中剔除。然后每个post请求得到响应后,将请求队列中对应的对象剔除掉。
具体代码是这样的:
var interceptor = { reqQueue: [], timeout: 30000, beforeRequest: function(req) { if (req.method === "post") { // 创建请求对象 var curReq = { url: req.url, data: JSON.stringify(req.data), timestamp: Date.now() }; // 检测是否重复请求 if (this.reqQueue.findIndex(item => item.url === curReq.url && item.data === curReq.data) === -1) { // 非重复请求添加到请求队列 this.reqQueue.push(curReq); } else { // 重复请求丢弃掉 req.abort(); } // 过滤掉超时请求 this.reqQueue = this.reqQueue.filter(item => { return Date.now() - item.timestamp < this.timeout }); } }, afterResponse: function(req, res) { if (req.method === "post") { // 过滤掉已完成请求 this.reqQueue = this.reqQueue.filter(item => item.url === req.url && item.data === JSON.stringify(req.data)); } } }
ajax 防止重复提交处理:
客户端:
1. disabled 提交按钮
2. 定义个变量 var hasSubmit = false,来处理。
服务端:
.....................
请搜索 CSRF
你点击按钮的时候,给这个按钮加上一个
class
,比如ub-click-able
,如果有这个class
,点击这个按钮不触发Ajax
事件。当Ajax
处理返回之后,你去掉这个class
。提交后加 disabled 属性。
这是个大问题,服务器端最好还是要有检查策略,一般关键性的,容易重复提交的request会通过一些参数来保证是合法客户端合法用户的合理请求,像淘宝前端是采集你的各种操作、当前时间、随机码等等来拼成一个token,后端有对应算法来验证这个,保证你没法重复提交。
重复提交一般针对post请求,我的处理方法是这样:
维护一个请求队列,每次post请求过来,生成一个包含url,data,timestamp的对象,push到队列中,后续每来一个post请求都对比一下,看请求队列中是否有url相同并且data相同的请求,如果有则认为是重复请求,当前请求丢弃掉。然后再遍历一下请求队列,比较每一个请求对象的timestamp和当前的timestamp,看请求是否超时,超时的话就将请求从队列中剔除。
然后每个post请求得到响应后,将请求队列中对应的对象剔除掉。
具体代码是这样的: