之前的做法 就是把按钮给禁用掉,
突然 想起文本框里敲回车 还是会提交表单。
现在打算用一变量来标记是否已经点击了提交。
我想知道的是 还有没别的 更优雅的方法?
之前的做法 就是把按钮给禁用掉,
突然 想起文本框里敲回车 还是会提交表单。
现在打算用一变量来标记是否已经点击了提交。
我想知道的是 还有没别的 更优雅的方法?
我觉得,你弄错了问题的重心。 首先,在前端上的修改并不能阻止用户的提交,这个世界上有很多专门用来修改页面的工具,Chrome?FireBug? 那么你真正的工作量应该是在后段。 其次,这时候才开始考虑前端的屏蔽,那么就Easy多了,随便用一个什么方式,关了submit就可以了啊,不需要想那么多的。
==========================================================================
用户分两种: 普通用户:你随便设置一个什么障碍,他们就得乖乖的等着,等到你的按钮可以点的时候。 开发者用户:对于他们来说,他们直接面对你的服务器。他们可能会copy你的数据,然后直接发送给你的服务器,每秒上百次甚至更多。也就是说,理论上你的前段并不在你的控制下。
用一个变量加锁
var lock = false;
执行Ajax的事件起初处判断
if (lock) {return;}
在Ajax发送前
lock = true;
在Ajax返回或错误后的回调函数中
lock = false;
如果你觉得无效化按钮挺优雅的话,那可以把整个表单都无效化加上 disabled
,就不担心回车的问题了,嫌麻烦还有简单的。
写一个loading
.loading {
position: absolute;
z-index: 10000;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: url(...) center center;
}
然后像上面的变量一样的,加锁时放入这个loading的标签,比如
$('form').append($('div').addClass('loading'));
回调后解锁时删除它
$('form').find('.loadding').detach();
@Tychio 的回答一句很好的回答了如何再前端防止重复提交了,我补充一个在后端判断的逻辑。可以在form里面添加一个隐藏域,值是随机的。如果有连续两次的请求值相同,说明是重复提交了,后面的提交可以舍弃。
我的解决方式是: 发送前判断按钮的状态,判断 data-state 属性值 是否为1 如果为1,return false; 不为1,则设置这个属性值为1,然后进行ajax操作,在ajax返回结果后,再把该属性值改为0.
提交发生后,直接禁用输入框和提交按钮就行了。
<form id="search">
<input type="text">
<input type="submit">
</form>
<script>
$("#search").bind("submit", function(e) {
e.preventDefault();
$("input").attr({"disabled": "disabled"});
// ajax code here
//....
});
</script>
这种避免重复提交的验证,应该前端和后端都应该验证,前端验证的方式就是禁用submit,或者弄一个模态框,当请求成功后再去掉模态框。后端验证就容易了,通过redis或者session来存储用户的请求的ip信息。
难道是我理解错了题意,这个不就是一句return false就能解决的问题吗?
$('form').submit(function(){//当表单被提交时,触发
$.ajax({
// do somethings
});
return false; //靠return false来阻止html的表单动作,让所有的表单动作都交给JS来处理。
});
当然,还可以通过event.preventDefault()也能阻止表单默认的提交动作
我一般也是采用这种方式,但不知你的实现手法是否和我的一样。
『文本框里敲回车』实际是触发form表单里的<button type="submit">按钮,你可以为这个button添加disabled属性:
这样就不会触发form表单的submit事件了。
如果你是绑定了这个按钮的click事件,那可以检测它是否有disabled属性,有的话直接return就好了。