前端jquery防止数据重复提交

更新日期: 2020-05-18 阅读: 2.5k 标签: jquery

背景

前端在向后端进行数据提交的时候,通常会需要在第一次提交返回前,阻止用户在快速点击发送二次请求,即防止重复提交,最简单的方法是使用标志参数或者 class 元素控制,但缺点是,每个控制重复提交的地方都需要加上这个逻辑,重复性太强,且控制逻辑不统一。

目前前端使用的是http协议,所以提交方式为两种

异步提交,使用jquery.ajax()
form 表单同步提交


异步防重复提交的方案如下

通过 jQuery 提供的 ajaxPrefilter 方法,将在请求提交之前进行过滤,仅保留第一次请求,后续的请求 abort 阻止掉,具体实现代码如下

/**
* _pendingRequests = {
* 'http:xxx.xxxx.do':['domain=P2P','xxxx=aaa'],
* 'http:xxx.yyyy.do':['domain=P3P','xxxx=bbb']
* }
* 该对象的 key 是请求的 url ,value 是由请求参数转化成的字符串数组
*/
var _pendingRequests = {};
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
var p_item = { //保存请求请求的url
key: options.url,
index: 0
},
dataArray = options.data ? options.data.split('&') : [];
compareData = function(beforD, afterD) {
//当url相同时,以此比较保存的参数对象,若参数对象相同,则返回false,若第一个就相同,则跳出循环
// 反之说明当前参数对象列表中没有与将要提交的参数相同,则可看为不同的请求,返回true,允许发起请求
var result = false;
for (var i = 0; i < beforD.length; i++) {
if (beforD[i]) {
result = false;
var beforData = beforD[i];
for (var j = 0; j < beforData.length; j++) {
if (afterD[j] !== beforData[j]) {
result = true;
break;
}
}
if (!result) {
break;
}
} else {
result = true;
continue;
}
}
return result;
};

//若请求队列中不存在或者同一个请求不同参数,且不为html后缀,则加入队列中
if ((!_pendingRequests[p_item.key] || compareData(_pendingRequests[p_item.key], dataArray)) && p_item.key.indexOf(
'.html') === -1) {
//给 index 赋值是因为请求是异步返回的,index用于标记第一个请求
if (_pendingRequests[p_item.key]) {
p_item.index = _pendingRequests[p_item.key].push(dataArray) - 1;
} else {
_pendingRequests[p_item.key] = [dataArray];
p_item.index = 0;
}
} else if (p_item.key.indexOf('.html') === -1) {
jqXHR.abort(); // 放弃后触发的重复提交,仅保留第一次提交
//pendingRequests[key].abort(); // 放弃先触发的提交
}
var complete = options.complete;
//请求完成
options.complete = function(jqXHR, textStatus) {
// 通过 key 和 index 获取成功返回的请求,将其值为 null ,下一次该请求便是在请求队列中便是新的一个请求
_pendingRequests[p_item.key][p_item.index] = null;
if ($.isFunction(complete)) {
complete.apply(this, arguments);
}
};
});


表单提交防重复提交的方案如下

表单的处理就稍微要麻烦点,但大致思路和异步的相同,等待第一次请求返回的同时,阻止后续触发的请求发送
首先基于jquery扩展了一个自定义的方法,如下

$.fn.preventDoubleSubmission = function() {
$(this).on('submit', function(e) {
var $form = $(this);
// $form.data('submitted') 通过该变量判断请求的状态
if ($form.data('submitted') === true) {
//阻止请求
e.preventDefault();
} else {
$form.data('submitted', true);
if ($form.attr('target') === '_blank') {
setTimeout(function() {
$form.data('submitted', false);
}, 800);
}
}
});
return this;
};


小贴士

提交按钮需使用 type='submit' ,因为监听的是表单的submit事件

不建议多次监听submit事件,会导致放重复提交失效

在表单提交前通常会有些表单检验的操作,所以当校验失败的时候,可以通过 event.preventDefault() 阻止表单提交


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/9487

相关推荐

jquery分页插件pagination.js报错pagination is not a function的bug解决方法

在使用jquery.pagination.js插件的时候,会出现pagination is not a function的错误,这是什么原因导致的呢?这里为大家整理一下,请对比自己的代码参考!

jQuery属性操作之.val()函数

val()实例方法的三种用法:.val() : 获取匹配的元素集合中第一个元素的当前value属性值(property).val(value) : 设置匹配的元素集合中每个元素的value属性值(property).val(function(index,value){}) :钩子函数未设置或无效时

jQuery动画的hover连续触发动画bug处理_让hover事件只触发一次动画的实现

一个简单的鼠标滑过的动画而已,但是当我测试的时候发现。事件就被触发了多次,动画也就重复了多次,怎么才能不重复出现,这是由于元素绑定hover事件之后,如果光标移入移出的速度太快,导致移入的动画还没执行完。

jquery实现点击控制div的显示和隐藏

我们使用点击显示、点击隐藏的时候,一般有两种可选方案,toggle() 的作用就是当对象是显示的就隐藏,当是隐藏的则显示

JQuery 自动触发事件

在JQuery中,可以使用trigger()方法完成模拟操作,trigger()方法不仅能触发浏览器支持的具有相同名称的事件,也可以触发自定义名称的事件。rigger(type[,data])方法有两个参数

jquery设置属性attr

jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式。attr(属性名)、attr(属性名, 属性值)、attr(属性名,函数值)、attr(properties)

是时候和 jQuery 说拜拜了么?

在网络上也时不时会看到,“是时候和jQuery说拜拜了”,最著名的莫过于在2013年的这篇文章You Might Not Need jQuery。

原生JS替代jQuery的各种方法汇总

前端发展很快,现代浏览器原生 API 已经足够好用。我们并不需要为了操作 DOM、Event 等再学习一下 jQuery 的 API。同时由于 React、Angular、Vue 等框架的流行,直接操作 DOM 不再是好的模式,jQuery 使用场景大大减少。

原生js中DOM对象转成jQuery对象、jQuery 对象转成 DOM 对象的实现

jquery是对js语言的封装、扩展,实现了对浏览器的兼容,使用jquery能让操作更方便简洁,这篇文章主要讲解原生js中Dom对象和jquery对象的相互转换。

Jquery插件开发的方法总汇

jquery插件是用来扩展jquery对象的一种方法,它的使用方法是通过jquery对象$来调用。其中Jquery插件开发一共有三种方式:$.extend(),$.fn,$.widget()

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!