terminar solicitud peticion llamada finalizar detener conexion como cerrar cancelar javascript jquery ajax

javascript - solicitud - finalizar ajax



Abortar peticiones Ajax usando jQuery (18)

Con jQuery, ¿cómo puedo cancelar / abortar una solicitud de Ajax de la que aún no he recibido la respuesta?


Como muchas personas en el subproceso han notado, solo porque la solicitud se cancela en el lado del cliente, el servidor todavía procesará la solicitud. Esto crea una carga innecesaria en el servidor porque está haciendo un trabajo que hemos dejado de escuchar en el front-end.

El problema que estaba tratando de resolver (para que otros también puedan ejecutarlo) es que cuando el usuario ingresó información en un campo de entrada, quise lanzar una solicitud para una sensación de tipo Google Instant.

Para evitar el envío de solicitudes innecesarias y para mantener la velocidad de la interfaz, hice lo siguiente:

var xhrQueue = []; var xhrCount = 0; $(''#search_q'').keyup(function(){ xhrQueue.push(xhrCount); setTimeout(function(){ xhrCount = ++xhrCount; if (xhrCount === xhrQueue.length) { // Fire Your XHR // } }, 150); });

Básicamente, esto enviará una solicitud cada 150 ms (una variable que puede personalizar para sus propias necesidades). Si tiene problemas para entender qué está sucediendo exactamente aquí, registre xhrCount y xhrQueue en la consola justo antes del bloque if.


El siguiente código muestra el inicio y el aborto de una solicitud Ajax:

function libAjax(){ var req; function start(){ req = $.ajax({ url: ''1.php'', success: function(data){ console.log(data) } }); } function stop(){ req.abort(); } return {start:start,stop:stop} } var obj = libAjax(); $(".go").click(function(){ obj.start(); }) $(".stop").click(function(){ obj.stop(); })

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input type="button" class="go" value="GO!" > <input type="button" class="stop" value="STOP!" >


Es una solicitud asíncrona , es decir, una vez que se envía, está ahí fuera.

En caso de que su servidor inicie una operación muy costosa debido a la solicitud de AJAX, lo mejor que puede hacer es abrir su servidor para escuchar las solicitudes de cancelación y enviar una solicitud de AJAX por separado para notificar al servidor que detenga lo que esté haciendo.

De lo contrario, simplemente ignora la respuesta AJAX.


Estaba haciendo una solución de búsqueda en vivo y necesitaba cancelar las solicitudes pendientes que pueden haber tomado más tiempo que la solicitud más reciente / más reciente.

En mi caso usé algo como esto:

//On document ready var ajax_inprocess = false; $(document).ajaxStart(function() { ajax_inprocess = true; }); $(document).ajaxStop(function() { ajax_inprocess = false; }); //Snippet from live search function if (ajax_inprocess == true) { request.abort(); } //Call for new request


Guarde las llamadas que realice en una matriz, luego llame a xhr.abort () en cada una.

CIGÜEÑA ENORME: puede abortar una solicitud, pero eso es solo del lado del cliente. El lado del servidor todavía podría estar procesando la solicitud. Si está utilizando algo como PHP o ASP con datos de sesión, los datos de la sesión se bloquean hasta que el ajax haya finalizado. Entonces, para permitir que el usuario continúe navegando en el sitio web, debe llamar a session_write_close (). Esto guarda la sesión y la desbloquea para que otras páginas que esperan continuar continúen. Sin esto, varias páginas pueden estar esperando a que se elimine el bloqueo.


He compartido una demo que demuestra cómo cancelar una solicitud AJAX, si los datos no se devuelven desde el servidor dentro de un tiempo de espera predefinido.

HTML:

<div id="info"></div>

CÓDIGO JS:

var isDataReceived= false, waitTime= 1000; $(function() { // Ajax request sent. var xhr= $.ajax({ url: ''http://api.joind.in/v2.1/talks/10889'', data: { format: ''json'' }, dataType: ''jsonp'', success: function(data) { isDataReceived= true; $(''#info'').text(data.talks[0].talk_title); }, type: ''GET'' }); // Cancel ajax request if data is not loaded within 1sec. setTimeout(function(){ if(!isDataReceived) xhr.abort(); },waitTime); });


La mayoría de los métodos jQuery Ajax devuelven un objeto XMLHttpRequest (o el equivalente), por lo que solo puede usar abort() .

Vea la documentación:

  • Método abortar ( MSDN ). Cancela la solicitud HTTP actual.
  • abort() ( MDN ). Si la solicitud ya se ha enviado, este método abortará la solicitud.

var xhr = $.ajax({ type: "POST", url: "some.php", data: "name=John&location=Boston", success: function(msg){ alert( "Data Saved: " + msg ); } }); //kill the request xhr.abort()

ACTUALIZACIÓN: A partir de jQuery 1.5, el objeto devuelto es un contenedor para el objeto XMLHttpRequest nativo llamado jqXHR. Este objeto parece exponer todas las propiedades y métodos nativos, por lo que el ejemplo anterior aún funciona. Consulte El objeto jqXHR (documentación de la API de jQuery).

ACTUALIZACIÓN 2: A partir de jQuery 3, el método ajax ahora devuelve una promesa con métodos adicionales (como abortar), por lo que el código anterior aún funciona, aunque el objeto que se devuelve ya no es un xhr . Vea el blog 3.0 aquí .

ACTUALIZACIÓN 3 : xhr.abort() aún funciona en jQuery 3.x. No asuma que la actualización 2 es correcta. Más información sobre el repositorio jQuery Github .


Las solicitudes de AJAX pueden no completarse en el orden en que se iniciaron. En lugar de abortar, puede optar por ignorar todas las respuestas AJAX, excepto la más reciente:

  • Crear un contador
  • Incrementa el contador cuando inicias la solicitud de AJAX.
  • Utilice el valor actual de contador para "sellar" la solicitud
  • En la devolución de llamada exitosa, compare el sello con el contador para verificar si fue la solicitud más reciente

Esquema aproximado del código:

var xhrCount = 0; function sendXHR() { // sequence number for the current invocation of function var seqNumber = ++xhrCount; $.post("/echo/json/", { delay: Math.floor(Math.random() * 5) }, function() { // this works because of the way closures work if (seqNumber === xhrCount) { console.log("Process the response"); } else { console.log("Ignore the response"); } }); } sendXHR(); sendXHR(); sendXHR(); // AJAX requests complete in any order but only the last // one will trigger "Process the response" message

Demo en jsFiddle


No puede recuperar la solicitud, pero puede establecer un valor de tiempo de espera después del cual se ignorará la respuesta. Ver esta page para jquery AJAX opciones. Creo que se llamará su error de devolución de llamada si se excede el período de espera. Ya hay un tiempo de espera predeterminado en cada solicitud AJAX.

También puede usar el método abort() en el objeto de solicitud, pero si bien el cliente dejará de escuchar el evento, es probable que no impida que el servidor lo procese.


Puedes abortar cualquier llamada continua ajax usando este

<input id="searchbox" name="searchbox" type="text" /> <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script> <script type="text/javascript"> var request = null; $(''#searchbox'').keyup(function () { var id = $(this).val(); request = $.ajax({ type: "POST", //TODO: Must be changed to POST url: "index.php", data: {''id'':id}, success: function () { }, beforeSend: function () { if (request !== null) { request.abort(); } } }); }); </script>


Si xhr.abort(); causa la recarga de la página,

Luego puede configurar onreadystatechange antes de abortar para evitar:

// ↓ prevent page reload by abort() xhr.onreadystatechange = null; // ↓ may cause page reload xhr.abort();


Siempre es una buena práctica hacer algo como esto.

var $request; if ($request != null){ $request.abort(); $request = null; } $request = $.ajax({ type : "POST", //TODO: Must be changed to POST url : "yourfile.php", data : "data" }).done(function(msg) { alert(msg); });

Pero es mucho mejor si verifica una instrucción if para verificar si la solicitud ajax es nula o no.


Simplemente llame a xhr. abortar () si se trata de un objeto ajax jquery o un objeto XMLHTTPRequest nativo.

ejemplo:

//jQuery ajax $(document).ready(function(){ var xhr = $.get(''/server''); setTimeout(function(){xhr.abort();}, 2000); }); //native XMLHTTPRequest var xhr = new XMLHttpRequest(); xhr.open(''GET'',''/server'',true); xhr.send(); setTimeout(function(){xhr.abort();}, 2000);


Simplemente use ajax.abort (), por ejemplo, podría abortar cualquier solicitud de ajax pendiente antes de enviar otra como esta

//check for existing ajax request if(ajax){ ajax.abort(); } //then you make another ajax request $.ajax( //your code here );


Solo tuvimos que solucionar este problema y probar tres enfoques diferentes.

  1. cancela la solicitud como lo sugiere @meouw
  2. Ejecutar todas las solicitudes pero solo procesa el resultado del último envío.
  3. Previene nuevas solicitudes siempre que haya otra pendiente.

var Ajax1 = { call: function() { if (typeof this.xhr !== ''undefined'') this.xhr.abort(); this.xhr = $.ajax({ url: ''your/long/running/request/path'', type: ''GET'', success: function(data) { //process response } }); } }; var Ajax2 = { counter: 0, call: function() { var self = this, seq = ++this.counter; $.ajax({ url: ''your/long/running/request/path'', type: ''GET'', success: function(data) { if (seq === self.counter) { //process response } } }); } }; var Ajax3 = { active: false, call: function() { if (this.active === false) { this.active = true; var self = this; $.ajax({ url: ''your/long/running/request/path'', type: ''GET'', success: function(data) { //process response }, complete: function() { self.active = false; } }); } } }; $(function() { $(''#button'').click(function(e) { Ajax3.call(); }); })

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input id="button" type="button" value="click" />

En nuestro caso, decidimos usar el enfoque # 3 ya que produce menos carga para el servidor. Pero no estoy 100% seguro de si jQuery garantiza la llamada del método .complete (), esto podría producir una situación de interbloqueo. En nuestras pruebas no pudimos reproducir tal situación.


Tuve el problema del sondeo y una vez que se cerró la página, el sondeo continuó, por lo que en mi causa, un usuario perdería una actualización, ya que se estaba configurando un valor de mysql para los siguientes 50 segundos después del cierre de la página, aunque eliminé la solicitud de ajax. descifrado, usar $ _SESSION para establecer una var no se actualizará en la encuesta hasta que finalice y comience una nueva, así que lo que hice fue establecer un valor en mi base de datos como 0 = offpage, mientras que Encuestando pregunto esa fila y devuelvo falso; cuando es 0, ya que la consulta en el sondeo obtendrá los valores actuales, obviamente ...

Espero que esto haya ayudado


no hay una forma confiable de hacerlo, y ni siquiera lo intentaría, una vez que la solicitud esté en marcha; La única forma de reaccionar razonablemente es ignorar la respuesta.

en la mayoría de los casos, puede suceder en situaciones como: un usuario hace clic con demasiada frecuencia en un botón que activa muchos XHR consecutivos, aquí tiene muchas opciones, ya sea bloquear el botón hasta que se devuelva XHR, o incluso no activar un nuevo XHR mientras otro está ejecutando pistas el usuario se incline hacia atrás o descarte cualquier respuesta XHR pendiente, pero la reciente.