jQuery: establece la prioridad del controller Ajax

en realidad, la pregunta es tan simple como dice el tema. ¿Hay alguna manera de dar a los diferentes manejadores ajax una prioridad mayor / menor (lo que significa aquí, que van a disparar antes)?

¿Que quiero decir? Bueno, tengo que lidiar con una aplicación web bastante grande. Toneladas de requestes de Ajax se disparan en diferentes modules. Ahora, mi objective es implementar un mecanismo simple de time de espera de session. Cada request envía el ID de session actual como parámetro, si el ID de session ya no es válido, mi script backend devuelve la request con un set de encabezado de respuesta personalizado (value es un uri).

Así que básicamente estoy yendo así

window.jQuery && jQuery( document ).ajaxComplete(function( event, xhr, settings ) { var networkingirectto = xhr.getResponseHeader( 'new_ajax_location' ); if( networkingirectto ) { location.href = networkingirectto; } }); 

Esto funciona como un encanto, por supuesto, pero mi problema es que este evento global de Ajax en realidad necesita ser disparado primero el 100% del time, lo que no es el caso. Algunos de los gestores de requestes ajax originales arrojarán un error debido a datos faltantes o inesperados, en ese caso, el controller global nunca se ejecutará.

Ahora, sería un poco feliz si no tuviera que pasar por cada controller de request y hacerlo a testing de fallas para las respuestas de datos de session no válidos. Preferiría mucho más hacer el trabajo en un lugar en particular. Pero, ¿cómo puedo asegurarme de que mi manejador global se ejecute primero?

Si lo entiendo correctamente, quiere agregar su propia callback a las requestes JSON en todas partes. Podría usar el gancho ajaxPrefilter.

  $.ajaxPrefilter(function( options, originalOptions, jqXHR ) { options.complete = function (jqXHR2, settings) { var networkingirectto = jqXHR2.getResponseHeader( 'new_ajax_location' ); if( networkingirectto ) { location.href = networkingirectto; } } }); 

También puede cambiar las opciones allí para agregar el ID de session a los parameters de request.

jQuery le permite "parchar" sus methods, como .post / .ajax.

Es posible que pueda aplicar un parche a los methods apropiados para que su evento especial AJAX siempre se active antes del que su código desea llamar.

Este es un "código pseudo-jQuery" que debería ayudarlo a comenzar. Dudo que funcione como está, pero demuestra el concepto básico y debería ayudarte a empezar.

 (function( $ ){ var originalPost = $.post; var calledSpecialOne = false; $.post = function(url, data, success, dataType) { if (!calledSpecialOne) { originalPost( ... your special AJAX query ... ).then( function() { originalPost(url, data, success, dataType); } calledSpecialOne = true; } else { originalPost(url, data, success, dataType); } } })( jQuery ); 

Lo anterior se basa en otro código no relacionado que he probado, que hace que $ .each () funcione para matrices indefinidas / nulas:

 (function($){ var originalEach = $.each; $.each = function(collection, callback) { return collection? originalEach(collection, callback) : []; } })(jQuery); 

Tenga en count que muchas funciones expuestas también son llamadas internamente por jQuery, así que tenga MUCHO cuidado usando este truco; puede romper una parte diferente de jQuery o causar otro problema. En el caso de las funciones AJAX, probablemente debería parchear la function más interna solamente, para evitar la recursión infinita. (FWIW, no he encontrado ningún efecto secundario para el parche $ .each () hasta ahora).

No estoy seguro de si esto es incluso lo que querías decir, pero pensé que podría necesitarlo como un punto de todos modos.

Parchea la function ajax de jQuery para aceptar un object con la priority propiedad. Si no hay una prioridad establecida, su prioridad es 1 (prioridad más alta 0). Si hay una prioridad, hace una de dos cosas. Si la prioridad es algo así como 5, verifica si se llamó a la llamada ajax con la prioridad previa (en este caso 4). Si no, lo agrega a un set de llamadas ajax con esa prioridad (en este caso 5). Si se ha llamado a la prioridad anterior, llama a la request normalmente. Cuando se llama a una request con una prioridad, llama a cualquier request saliente con la siguiente prioridad más alta.

En otras palabras, si no hay prioridad, espera prioridad 0, si hay una prioridad, espera a que se llame la prioridad debajo de ella. Si desea que las llamadas sin prioridad se envíen inmediatamente, comente la línea con el comentario que puse diciendo default action?

  (function( $ ){ var oldAjax=$.ajax; var outgoing=[]; var sent=[]; $.ajax=function(url, settings) { var pr = (typeof url==='object'?url:settings).priority; pr = pr===undefined ? 1 : pr; // default action? if(pr!==undefined){ if(pr==0 || sent[pr-1]!==undefined){ oldAjax(url,settings); sent[pr]=true; if(outgoing[pr]){ var rq=outgoing[pr].splice(0,1)[0]; $.ajax(rq[0],rq[1]); } if(outgoing[pr+1]){ var rq=outgoing[pr+1].splice(0,1)[0]; $.ajax(rq[0],rq[1]); } } else{ if(outgoing[pr]!==undefined){ outgoing[pr].push([url,settings]); } else{ outgoing[pr]=[[url,settings]]; } } } else{ oldAjax(url, settings); } }; })( jQuery ); 

Parches para get y post . Deberá include esos arguments adicionales o cambiarlos usted mismo para get la prioridad de trabajo con post requestes de post y get . Esto es directamente desde jQuery 1.7, excepto por el argumento adicional, y las dos líneas a las que agregué comentarios.

  jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type, priority ) { // shift arguments if data argument was omitted if ( jQuery.isFunction( data ) ) { priority = type; // my change type = type || callback; callback = data; data = undefined; } return jQuery.ajax({ type: method, url: url, data: data, success: callback, dataType: type, priority: priority // my change }); }; }); 

Configuré un ejemplo aquí: http://jsfiddle.net/tk39z/

De hecho, creé algunas requestes ajax orientadas a google, por lo que puedes consultar el panel de networking en Chrome para ver las requestes.

Recientemente implementé algo muy similar a la funcionalidad que creo que estás buscando.

Configuré un filter en el lado del server para probar una session válida y, si no, devuelvo un error 401 con text de estado personalizado para un detalle de error más específico.

Las llamadas ajax que hice a estas páginas fueron escritas en la convención normal usando el atributo 'éxito'.

Para las situaciones en las que hubo un error, agregué una callback global a la function de error que probaría el error específico y networkingirigiría en consecuencia. como:

 $( document ).ajaxError(function(e, xhr) { var networkingirectto = xhr.getResponseHeader( 'new_ajax_location' ); if( networkingirectto ) { location.href = networkingirectto; } });