我正在尝试在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”,但是在成功之后,我看不到调试的开始和结束消息。

我做错了什么?

最佳答案

您想要完成的工作无法使用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().load())在内部都使用$.ajax,因此,它应该与通过jQuery完成的每个AJAX请求一起使用(尽管我没有对此进行测试...)。

像这样的事情也应该通过入侵XMLHttpRequest.prototype与“纯” JavaScript一起工作。请注意,以下内容在使用ActiveXObject而不是XMLHttpRequest的IE中不起作用。
(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();

关于javascript - 如何通过JQuery ajaxSend事件覆盖成功函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12003978/

10-11 05:45