我认为我遇到了一个经典问题,但到目前为止我找不到合适的解决方案。
我有一个表单,用户单击“发送”,一切正常,使用PRG模式并进行客户端和服务器端验证。
当服务器脚本结束执行之前,任何用户(让我们假设他输入有效输入)快速点击一次就会出现问题...
我没有得到任何重复的条目,因为我处理了这个,但浏览器没有转到我的“感谢提交页面”。 相反,它重新提交具有相同值的同一页面,我得到的是我设置的自定义错误,警告用户他试图输入已存储在数据库中的详细信息。首先发送的详细信息都在数据库中,但用户没有机会知道。
我尝试使用jQuery禁用提交事件的提交按钮,但在这种情况下,数据不会被提交。
HTML
<div id="send-button-container">
<input id="send-emails" type="submit" name="send_emails" value="Send"/>
</div>
的jQuery
$(document).ready(function(){
$('#mail-form').submit(function(){
$('#send-emails').attr('disabled','disabled');
});
});
我想知道我是否可以在禁用按钮后使用Javascript强制提交,以及如何在禁用Javascript的情况下处理UA
提前致谢
答案 0 :(得分:3)
根据服务器端语言,禁用提交按钮可能会导致问题。这是因为禁用的元素未发布到服务器。像ASP.NET这样的语言需要提交按钮值,因此它知道要触发的事件处理程序。我通常做的是隐藏提交按钮,并在其后插入一个禁用的虚拟按钮,它看起来与用户相同。然后在你的onsubmit处理程序中,你可以返回false并以编程方式提交表单......
$('#mail-form').submit(function(){
var btn = $('#send-emails');
var disBtn = $("<input type='button'/>").val(btn.val()).attr("disabled", "disabled");
btn.hide().after(disBtn);
this.submit();
return false;
});
与其他投票的答案相反,请注意您不需要从提交处理程序中明确返回true以进行自然表单提交:http://jsfiddle.net/XcS5L/3/
答案 1 :(得分:1)
你必须return true
;如果你想要一个简单的按钮来提交表格,你可以试试这个。
$(function(){
$('#submitID').one('click',function(){
$('#formTobeSubmitted').submit();
$(this).attr('disabled','disabled');
})
});
答案 2 :(得分:1)
在服务器端,在每个表单中生成一个随机数,在提交表单时存储该号码,如果该号码早先已存储,则丢弃该提交。当用户禁用了javascript时,这是您可以做的最好的事情。 (并发问题可能很棘手,因为同时处理两个相同的请求 - 请确保使用某种锁定机制,例如具有唯一字段的表或PHP中的flock()命令。)
在浏览器端,只需在提交表单时设置一个标志,并丢弃所有后续提交的内容:
$('#mail-form').submit(function() {
if ($(this).data('submitted') {
return false;
} else {
$(this).data('submitted', true).addClass('submitted');
}
});
您可以使用submitted
类将按钮设置为灰色或其他内容。简单地禁用它们有一些好处;乔希已经说过了一个。另一个原因是,当你点击刷新时,Firefox喜欢记住禁用状态,这可能会导致用户在某些情况下陷入困境。
答案 3 :(得分:1)
我认为这意味着您依赖于提交按钮的值来为请求提供服务?那是你在检查
$_REQUEST['send_emails'] == 'Send';
这不是好习惯。您永远不应该依赖提交按钮的值,因为这正是向用户显示的内容。相反,您应该添加一个隐藏的输入,其中包含您要触发的事件。提交表单后,您无需关心提交按钮的值是什么,您可以禁用它。表格中的所有其他非禁用数据仍然会被提交。
禁用按钮后,您确实可以强制提交。
$(function () {
$("#mail-form").submit(function () {
$("#send-emails").attr('disabled', 'disabled');
window.location = '?' + $("#mail-form").serialize() + '&send_mails=Send';
return false;
});
});
服务器端设置一个$ _SESSION变量,用于跟踪他们上次提交内容并在一定时间内阻止提交。
<?php
session_start();
if (isset($_REQUEST['send_emails'])) {
if (isset($_SESSION['mail_sent'])
&& strtotime($_SESSION['mail_sent']) < strtotime('5 seconds ago')
) {
redirect_to_thanks();
}
do_post();
}
function do_post() {
if (do_validate()) {
$_SESSION['mail_sent'] = time();
redirect_to_thanks();
}
else {
yell_at_user_a_lot();
}
}
?>
答案 4 :(得分:0)