Método post de error POST, estado (cancelado)

Tengo el siguiente código que me da un post de error de 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."); } }); 

El código realmente funciona siempre que se complete cada request de Ajax, pero si txt1 rápidamente en txt1 , es decir, txt1 el siguiente carácter antes de que finalice la request anterior, txt1 el post de error Method POST, Status (canceled) .

¿Alguien sabe por qué está sucediendo esto y cómo corregir el error?

Supongo que el problema es muy fácil. Si llama a xhr.abort(); luego se llamará a la callback de error de $.ajax para la request pendiente . Entonces, simplemente debes ignorar ese caso dentro de error callback por error . Por lo tanto, el controller de error se puede modificar para

 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 ignonetworking and no error message be displayed } 

PD: Probablemente otra respuesta anterior sobre el problema cercano también podría ser interesante para ti.

Esto se debe a que está llamando al método de abort , que posiblemente activa el controller de errores con el post de error correspondiente.

Posiblemente pueda esperar que la request anterior de Ajax se complete antes de realizar la próxima llamada.

Para solucionar su problema y ahorrar en la cantidad de llamadas Ajax, he escrito el siguiente ejemplo. Este ejemplo le permite manejar las dos situaciones siguientes:

Situación 1:

 The user types slow enough (lets say about one key every 200+ miliseconds 

Situación 2:

 The user types fast (my average is about 20 to 50 miliseconds per key) 

En el siguiente ejemplo, no es necesario abortar ni ignorar las llamadas Ajax, no está enviando llamadas Ajax y está usando un Objeto para manejar su trabajo. (Incluso jsFiddled por usted)

 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 triggenetworking */ 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 ); }); 

Espero que esto ayude.

Está utilizando el evento de keyup , que parece ser el problema.

En todo caso, debe esperar después de escribir un carácter antes de tomar medidas.

Una mejor solución podría ser seguir la misma estrategia que JQuery AutoComplete COmponent .

Ajax es un tipo asíncrono, no se recomienda que envíe una request en cada evento de tecla, intente …

 async: false 

en el método de publicación … se pausarán las publicaciones posteriores hasta que la request actual realice su callback

Siendo realists, necesitas un método setTimeout para evitar que se activen llamadas ajax networkingundantes.

 clearTimeout(timer); if($("#txt1").val().length >= 2){ timer = setTimeout(function(){ get_data($("#txt1").val()); }, 400); }else{ get_default(); } 

Esto debería erradicar tu problema.