2012-03-29 21 views
11

Tengo el siguiente código que me está dando un mensaje Method POST, Status (canceled) error:método POST, mensaje Estado (cancelado) de error

$(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 funciona realmente el tiempo que cada solicitud ajax completa, pero si escribir rápido en txt1, es decir, escriba el siguiente carácter antes de que finalice la solicitud anterior, aparece el mensaje de error Method POST, Status (canceled).

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

+0

Esto puede ser útil, eche un vistazo [stackoverflow.com/questions/6678467](http://stackoverflow.com/questions/6678467/ajax-sent-on-keyup-duplicates-results-when-fast -typing) – safarov

+0

Oleg tiene probablemente la mejor respuesta aquí. Su solución debería ayudarte a avanzar con el guión. SIN EMBARGO: mientras lees tu código, veo que no estás creando el código ideal para este problema. Crearé una respuesta para ti. –

Respuesta

11

Supongo que el problema es muy fácil. Si llama al xhr.abort();, la llamada de error de $.ajax se llamará para la solicitud pendiente. Entonces, simplemente debe ignorar tal caso dentro de la devolución de llamada error. Por lo que el manejador de error puede ser modificado 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 ignored and no error message be displayed 
} 

P. S. Probablemente otro mi old answer en el problema cercano también podría interesarle.

0

Esto se debe a que está llamando al método abort que posiblemente desencadena el controlador de errores con el mensaje de error apropiado.

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

+0

¿Cómo debo abortar un proceso que no ha terminado si otro necesita iniciarse en su lugar? – oshirowanen

-1

Ajax es un tipo asíncrono, no es recommonded que u para enviar solicitud en cada caso keyup, probar el ...

async: false 

en el método post ... que va a hacer una pausa en los puestos subsiguientes hasta que el solicitud actual realizada su devolución de llamada

+3

Usar 'async: false' no es aconsejable, ya que detendrá el navegador hasta que la solicitud se complete y responda. – ShankarSangoli

+0

Estoy de acuerdo. Con esta solución, destruyes toda la posibilidad de contenido agregado dinámicamente mientras escribes. –

0

Está utilizando el evento 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 el JQuery AutoComplete COmponent.

-1

Realísticamente necesita un método setTimeout para evitar que se activen llamadas ajax redundantes.

clearTimeout(timer); 

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

Esto debería erradicar su problema.

+0

¿Cómo es que esta respuesta no es útil? – trickyzter

0

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 hay necesidad de abortar o ignore las llamadas de Ajax, no está enviando llamadas de Ajax por correo basura y está usando un Objeto para manejar su trabajo.(I incluso jsFiddled es para 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 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); 

}); 

Espero que esto ayude.

Cuestiones relacionadas