Метод POST, сообщение об ошибке состояния (отменено)
У меня есть следующий код, который дает мне Method POST, Status (canceled)
сообщение об ошибке:
$(document).ready(function() {
var xhr = false;
get_default();
$('#txt1').keyup( function() {
if(xhr && xhr.readyState != 4){
alert("abort");
xhr.abort();
}
if ($("#txt1").val().length >= 2) {
get_data( $("#txt1").val() );
} else {
get_default();
}
});
function get_data( phrase ) {
xhr = $.ajax({
type: 'POST',
url: 'http://intranet/webservices.asmx/GetData',
data: '{phrase: "' + phrase + '"}',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function( results ) {
$("#div1").empty();
if( results.d[0] ) {
$.each( results.d, function( index, result ) {
$("#div1").append( result.Col1 + ' ' + result.Col2 + '<br />' );
});
} else {
alert( "no data available message goes here" );
}
},
error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message) ;
}
});
}
function get_default() {
$('#div1').empty().append("default content goes here.");
}
});
Код на самом деле работает до тех пор, пока завершается каждый ajax-запрос, но если я быстро наберу в txt1
, т.е. введите следующий символ до завершения предыдущего запроса, я получаю сообщение об ошибке Method POST, Status (canceled)
,
Кто-нибудь знает, почему это происходит и как исправить ошибку?
6 ответов
Я полагаю, что проблема очень проста. Если вы позвоните xhr.abort();
тогда error
обратный вызов $.ajax
будет вызван для ожидающего запроса. Так что вы должны просто игнорировать такой случай внутри error
Перезвоните. Итак error
обработчик может быть изменен на
error: function(jqXHR, textStatus, errorThrown) {
var err;
if (textStatus !== "abort" && errorThrown !== "abort") {
try {
err = $.parseJSON(jqXHR.responseText);
alert(err.Message);
} catch(e) {
alert("ERROR:\n" + jqXHR.responseText);
}
}
// aborted requests should be just ignored and no error message be displayed
}
PS Наверное, еще один мой старый ответ на близкую проблему тоже мог бы вас заинтересовать.
Вы используете keyup
событие, которое кажется проблемой.
Во всяком случае, вам нужно подождать после ввода одного символа, прежде чем предпринимать какие-либо действия.
Лучшее решение может заключаться в том, чтобы следовать той же стратегии, что и JQuery AutoComplete COmponent
,
Чтобы решить проблему и сэкономить на количестве вызовов Ajax, я написал следующий пример. Этот пример позволяет вам обрабатывать следующие две ситуации:
Ситуация 1:
The user types slow enough (lets say about one key every 200+ miliseconds
Ситуация 2:
The user types fast (my average is about 20 to 50 miliseconds per key)
В следующем примере нет необходимости прерывать или игнорировать вызовы Ajax, вы не спамуете вызовы Ajax и используете объект для обработки своей работы. (Я даже jsFiddled это для вас)
var Handler = {
/**
* Time in ms from the last event
*/
lastEvent: 0,
/**
* The last keystroke must be at least this amount of ms ago
* to allow our ajax call to run
*/
cooldownPeriod: 200,
/**
* This is our timer
*/
timer: null,
/**
* This should run when the keyup event is triggered
*/
up: function( event )
{
var d = new Date(),
now = d.getTime();
if( ( now - Handler.lastEvent ) < Handler.cooldownPeriod ) {
// We do not want to run the Ajax call
// We (re)set our timer
Handler.setTimer();
} else {
// We do not care about our timer and just do the Ajax call
Handler.resetTimer();
Handler.ajaxCall();
}
Handler.lastEvent = now;
},
/**
* Function for setting our timer
*/
setTimer: function()
{
this.resetTimer();
this.timer = setTimeout( function(){ Handler.ajaxCall() }, this.cooldownPeriod );
},
/**
* Function for resetting our timer
*/
resetTimer: function()
{
clearTimeout( this.timer );
},
/**
* The ajax call
*/
ajaxCall: function()
{
// do ajax call
}
};
jQuery( function(){
var field = jQuery( '#field' );
field.on( 'keyup', Handler.up );
});
Надеюсь это поможет.
Это потому что ты звонишь abort
метод, который, возможно, вызывает обработчик ошибок с соответствующим сообщением об ошибке.
Возможно, вы можете дождаться завершения предыдущего ajax-запроса, прежде чем делать следующий вызов.
Ajax является асинхронным типом, его не рекомендуется отправлять запрос на каждое событие keyup, попробуйте...
async: false
в методе post... он приостановит последующие сообщения, пока текущий запрос не выполнит обратный вызов
Реально вам нужен метод setTimeout, чтобы предотвратить запуск избыточных вызовов ajax.
clearTimeout(timer);
if($("#txt1").val().length >= 2){
timer = setTimeout(function(){
get_data($("#txt1").val());
}, 400);
}else{
get_default();
}
Это должно искоренить вашу проблему.