2012-08-17 3 views
5

Ich versuche, die Erfolgsfunktion auf ajaxsend Ereignis zu überschreiben, aber es funktioniert nicht hier zu arbeiten, ist der Code:wie die Erfolgsfunktion über JQuery ajaxSend Ereignis überschrieben

$(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;}); 

auf AJAX Ich sehe tun ‚Ajax‘ in die Konsole, aber nach Erfolg kann ich nicht sehen, den Start und das Ende Debug-Nachrichten ..

Was mache ich falsch?

+0

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

+0

Dank, aber es beantwortet meine Frage nicht, ajaxComplete wird ausgelöst, nachdem der Browser die HTTP-Antwort erhalten hat, ich frage nach ajaxSend, das vor der HTTP-Anfrage ausgelöst wird. – ciochPep

+0

Sie haben Recht. Ich habe gerade auf die Antwort hingewiesen, die besagt, dass Callbacks ausgeführt werden müssen und dass Sie das nicht verhindern können. Zugegeben, es ist nicht genau deine Frage. Ich bin auch an einer Lösung interessiert. – pimvdb

Antwort

-1

könnten Sie Verschlüsse verwenden, um zu erreichen, was Sie brauchen:

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

Dies funktioniert nicht wie vorgesehen, da die Erfolgs-Callback-Funktion nicht überschrieben wird! Die Funktion "Schließen" hat keine Wirkung; 'console.log ('start/end')' könnte auch hier in 'ajaxSend' verschoben werden.Im Grunde ist Ihre "Lösung" nur Code-Verschleierung ... – Aletheios

+0

Klar habe ich die Absicht des Autors missverstanden, sorry dafür. Wie für $ .get und $ .load verwenden sie intern $ .ajax intern, wie hier zu sehen ist: https://github.com/jquery/jquery/blob/master/src/ajax.js – prot

6

Was Sie versuchen können zu erreichen, nicht mit ajaxSend erfolgen. Das Problem ist, dass ajaxSend anscheinend mit einer Kopie der ursprünglichen xhr und options Objekte arbeitet, so dass die Änderungen keinen Effekt haben werden. Sie können dies einfach testen mit dem folgenden Code:

$(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"); } 
}); 


So können Sie nicht ajaxSend verwenden, um den Erfolg Rückrufe zu überschreiben. Stattdessen müssen Sie jQuery AJAX-Funktion „Hack“:

// 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); 
    }; 
})(); 

Jetzt können Sie einfach $.ajax wie gewohnt verwenden:

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

Soweit ich weiß, jeder von jQuery AJAX-Funktionen (wie zB $.get() oder .load()) intern verwenden $.ajax, so sollte dies mit jeder AJAX-Anfrage über jQuery (Ich habe dies nicht getestet, aber ...) funktionieren.



So etwas sollte auch mit "reinem" JavaScript arbeiten, indem sie die XMLHttpRequest.prototype Hacking. Beachten Sie, dass das folgende in IE nicht funktioniert, das ActiveXObject statt XMLHttpRequest verwendet.

(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); 
    }; 
})(); 

Nutzung (wie eine gewöhnliche XMLHttpRequest):

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

was würden Sie tun für nicht-jquery ajax Anfragen? – ciochPep

+0

Siehe oben, ich habe meine Antwort bearbeitet ... Aber ich denke, da ist mehr dran, also solltest du vielleicht eine separate Frage dafür aufschlagen. – Aletheios

Verwandte Themen