2012-08-17 75 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