是什么原因导致ajax同时发送多个POST请求?它很难重现,因为它发生在大约2%的时间。它似乎发生在糟糕/移动网络上。我们在Android上使用Chrome。
表格如何运作
问题 当系统只保存一个时,系统会保存多个记录。
我发现/尝试过的内容
[22 / Aug / 2016:07:14:12 -0700]" POST / api / save?p = 14718752538085 HTTP / 1.1" 200 749
[22 / Aug / 2016:07:14:12 -0700]" POST / api / save?p = 14718752538085 HTTP / 1.1" 200 736
事件绑定问题?我做了这个改变: https://stackoverflow.com/a/13475122/2537574 $(' #field')。取消绑定(' keyup')。keyup(function(e){
事件冒泡问题?我添加了这个: https://stackoverflow.com/a/12708948/2537574 的 e.stopImmediatePropagation();
尝试6 - 无法正常工作
unbind / bind是一种老式的做法。现在尝试使用.off和.on并添加e.preventDefault()。 (https://stackoverflow.com/a/14469041/2537574)
$(document).off('keyup', "#field").on('keyup',"#field" ,function(e) {
e.preventDefault();
...
尝试7 - 无法正常工作 将 return false 添加到keyup事件侦听器的末尾。
$(document).off('keyup', "#field").on('keyup',"#field" ,function(e) {
e.preventDefault();
// checks for 6 chars and submits
return false;
)};
尝试8 - 去抖动
$(document).off('keyup', "#field").on('keyup',"#field" ,debounce(function(e) {
// checks for 6 chars and submits
},50));
尝试9 - 更新了Web服务器Tomcat 更新到最新的tomcat 7.70,但没有解决问题。
当前代码
$(document).off('keyup', "#field").on('keyup',"#field" ,debounce(function(e) {
e.preventDefault(); // attempt 6
if(e.which != 13){
if($(this).val().length ==6){
submitForm();
$(this).val('');
}
}
return false; // attempt 7
},50));
function submitForm(){
// Does some validation and if it passes calls:
persist();
}
function persist(){
var data = $("#Form").serialize();
var persistNum = Date.now()+''+(Math.floor(Math.random() * 9)); // used to prevent duplicate insertion on POST retry
$.ajax({
url: "/api/save?pNum="+persistNum,
context:document.body,
cache: false,
type: "POST",
data: data,
success:function(data, textStatus, jqXHR){},
error: function(jqXHR, textStatus, errorThrown)
{}
});
}
答案 0 :(得分:0)
我无法确定这是你的问题,但是当你使用它来调用ajax时它绝对想要使用带有keyup的计时器,这样它只会在用户停止输入时触发。此外,我会跟踪提交状态,只有在尚未发送时才发送。这是我使用的,可以解决您的问题:
var ajaxProcessing = false; // keep track of submission state
$('#field').unbind('keyup').keyup(function(e) {
if (ajaxProcessing) return; // if processing, ignore keyup
var $this = $(this);
keyupDelay(function() { // keyup timer, see below
if (e.which != 13) {
if ($this.val().trim().length == 6) { // good UX to trim the value here ;)
submitForm();
}
}
}, 500); // this sets it to go off .5 seconds after you stop typing. Change as needed
});
function submitForm() {
// Does some validation and if it passes calls:
persist();
}
function persist() {
ajaxProcessing = true; // set is proccessing
var data = $("#Form").serialize();
$.ajax({
url: "/api/save",
context: document.body,
cache: false,
type: "POST",
data: data,
success: function(data, textStatus, jqXHR) {
ajaxProcessing = false;
$("#Form").find("input[type=text], textarea").val(""); // reset form here
},
error: function(jqXHR, textStatus, errorThrown) {
ajaxProcessing = false;
alert('Form was submitted. It failed though because ajax wont work from SO');
}
});
}
// keyup timer funtion
var keyupDelay = (function() {
var timer = 0;
return function(callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
input {
width: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="" id="Form">
<input type="text" maxlength="6" placeholder="type 6 chars here then stop" id="field">
</form>