2012-08-17 9 views
5

Estoy tratando de sobrescribir la función de éxito en caso ajaxsend pero no funciona Aquí está el código:cómo sobrescribir la función de éxito a través de evento jQuery ajaxSend

$(document).ajaxSend(function(event,xhr,options){ 
     console.log('ajaxSend'); 
     var tempSuccess = options.success; 
     options.success = function(data, textStatus, jqXHR){ 
      console.log('start'); 
      tempSuccess(data, textStatus, jqXHR); 
      console.log('end'); 
     }; xhr.success = options.success;}); 

sobre AJAX veo 'ajax' en la consola, pero en caso de éxito no puedo ver el inicio y el final de la depuración msges ..

¿Qué hago mal?

+0

relacionadas: http://stackoverflow.com/questions/293668/jquery-ajax-prevent-callback-from-running – pimvdb

+0

gracias, pero no responde a mi pregunta, ajaxComplete dispara después de que el navegador recibe la respuesta HTTP, estoy preguntando por ajaxSend que se dispara antes de la solicitud HTTP – ciochPep

+0

Tienes razón. Solo estaba señalando la respuesta que dice que las devoluciones de llamada se ejecutarán y que no se puede evitar eso. De acuerdo, no es exactamente tu pregunta; Estoy interesado en una solución también. – pimvdb

Respuesta

-1

Se puede usar cierres para lograr lo que necesita:

function closure(handler) { 
    return function(ev, xhr, options) { 
     console.log("start"); 
     handler(ev, xhr, options); 
     console.log("stop"); 
    } 
} 

$(document).ajaxSend(closure(function(ev, xhr, options) { 
    console.log("hello"); 
})); 
+0

¡Esto no funciona según lo previsto, ya que no sobrescribe la función de devolución de llamada exitosa! La función de "cierre" no tiene ningún efecto; 'console.log ('start/end')' podría también moverse a 'ajaxSend' aquí.Básicamente, su "solución" es solo ofuscación de código ... – Aletheios

+0

Claramente entendí mal la intención del autor, lo siento por eso. En cuanto a $ .get y $ .load utilizan $ .ajax internamente como se puede ver aquí: https://github.com/jquery/jquery/blob/master/src/ajax.js – prot

6

Lo que estamos tratando de lograr que no se puede hacer con ajaxSend. El problema es que ajaxSend aparentemente funciona con una copia de los objetos originales xhr y options, por lo que las modificaciones no tendrán ningún efecto. Se puede probar fácilmente esto con el siguiente código:

$(document).ajaxSend(function(event, xhr, options){ 
    delete options.success; 
    console.log(options.success); // undefined 
}); 
$.ajax({ 
    url: "test.html", 
    success: function() { console.log("this will be printed nevertheless"); } 
}); 


Así no se puede utilizar para sobrescribir ajaxSend las devoluciones de llamada de éxito. En su lugar, tendrá que "cortar" la función AJAX de jQuery:

// closure to prevent global access to this stuff 
(function(){ 
    // creates a new callback function that also executes the original callback 
    var SuccessCallback = function(origCallback){ 
     return function(data, textStatus, jqXHR) { 
      console.log("start"); 
      if (typeof origCallback === "function") { 
       origCallback(data, textStatus, jqXHR); 
      } 
      console.log("end"); 
     }; 
    }; 

    // store the original AJAX function in a variable before overwriting it 
    var jqAjax = $.ajax; 
    $.ajax = function(settings){ 
     // override the callback function, then execute the original AJAX function 
     settings.success = new SuccessCallback(settings.success); 
     jqAjax(settings); 
    }; 
})(); 

Ahora puede simplemente usar $.ajax como de costumbre:

$.ajax({ 
    url: "test.html", 
    success: function() { 
     console.log("will be printed between 'start' and 'end'"); 
    } 
}); 

Por lo que yo sé, ninguna de las funciones AJAX de jQuery (por ejemplo, $.get() o .load()) internamente use $.ajax, así que esto debería funcionar con cada solicitud AJAX hecha a través de jQuery (no he probado esto ...).



Algo así como que también debería funcionar con JavaScript "puro" por el pirateo de la XMLHttpRequest.prototype. Tenga en cuenta que lo siguiente no funcionará en IE, que usa ActiveXObject en lugar de XMLHttpRequest.

(function(){ 
    // overwrite the "send" method, but keep the original implementation in a variable 
    var origSend = XMLHttpRequest.prototype.send; 
    XMLHttpRequest.prototype.send = function(data){ 
     // check if onreadystatechange property is set (which is used for callbacks) 
     if (typeof this.onreadystatechange === "function") { 
      // overwrite callback function 
      var origOnreadystatechange = this.onreadystatechange; 
      this.onreadystatechange = function(){ 
       if (this.readyState === 4) { 
        console.log("start"); 
       } 
       origOnreadystatechange(); 
       if (this.readyState === 4) { 
        console.log("end"); 
       } 
      }; 
     } 
     // execute the original "send" method 
     origSend.call(this, data); 
    }; 
})(); 

uso (al igual que un XMLHttpRequest habitual):

var xhr = new XMLHttpRequest(); 
xhr.open("POST", "test.html", true); 
xhr.onreadystatechange = function(){ 
    if (xhr.readyState === 4) { 
     console.log("will be printed between 'start' and 'end'"); 
    } 
}; 
xhr.send(); 
+0

¿qué harías? para solicitudes no-jquery ajax? – ciochPep

+0

Ver más arriba, he editado mi respuesta ... Pero creo que hay más, así que quizás debas abrir una pregunta por separado. – Aletheios

Cuestiones relacionadas