2012-08-17 34 views
5

我試圖覆蓋在ajaxsend事件成功的功能,但它不工作 這裏是代碼:如何通過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;}); 

在AJAX我看到「AJAX」中控制檯,但成功後,我看不到開始和結束調試msges ..

我該怎麼做錯了?

+0

相關:http://stackoverflow.com/questions/293668/jquery-ajax-prevent-callback-from-running – pimvdb 2012-08-17 10:31:32

+0

感謝,但它不回答我的問題,在瀏覽器獲取HTTP響應後,ajaxComplete觸發,我詢問有關在HTTP請求之前觸發的ajaxSend – ciochPep 2012-08-17 10:39:38

+0

您是對的。我只是指出回答說必須運行回調,而且你不能阻止回調。當然,這不完全是你的問題;我也對解決方案感興趣。 – pimvdb 2012-08-17 10:42:20

回答

-1

你可以使用閉包來完成你所需要的:

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

這不符合預期,因爲它不會覆蓋成功回調函數! 「關閉」功能沒有任何作用; 'console.log('start/end')'也可以在這裏移入'ajaxSend'。基本上你的「解決方案」只是代碼混淆... – Aletheios 2012-08-17 18:08:25

+0

很明顯,我誤解了作者的意圖,對此抱歉。 至於$ .get和$ .load,它們在內部使用$ .ajax,如下所示:https://github.com/jquery/jquery/blob/master/src/ajax.js – prot 2012-08-17 19:44:18

6

你要完成什麼不能ajaxSend來完成。問題是,ajaxSend顯然與原始的xhroptions對象的副本一起使用,所以這些修改不會產生任何影響。您可以輕鬆地用下面的代碼測試:

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


所以你不能使用ajaxSend覆蓋成功回調。相反,你將不得不「黑客」 jQuery的AJAX功能:

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

現在,你可以簡單地使用$.ajax像往常一樣:

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

據我所知,任何的jQuery的AJAX功能(如$.get()或​​)在內部使用$.ajax,所以這應該適用於通過jQuery完成的每個AJAX請求(我還沒有測試過這個,儘管...)。



類似的東西也應該用「純」的JavaScript由黑客 XMLHttpRequest.prototype工作。請注意,以下內容在IE中不起作用,IE使用 ActiveXObject而不是 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); 
    }; 
})(); 

使用(就像一個平常的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

你會做什麼對於非jquery ajax請求? – ciochPep 2012-08-20 20:02:03

+0

請參閱上面的內容,我已經編輯了我的答案......但我想這裏面還有更多,所以也許你應該爲此打開一個單獨的問題。 – Aletheios 2012-08-21 00:22:16