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();
relacionadas: http://stackoverflow.com/questions/293668/jquery-ajax-prevent-callback-from-running – pimvdb
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
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