如何在事件处理程序之前用jQuery拦截ajax响应?

时间:2022-05-06 23:52:27

I'd like to register a global event handler for all AJAX requests, so that I can intercept and handle responses from the server before the specific event handler gets them.

我希望为所有AJAX请求注册一个全局事件处理程序,以便在特定的事件处理程序获得响应之前截获并处理服务器的响应。

For example, my code might have something like:

例如,我的代码可能有如下内容:

$("#placeholder").load("/fragments/userpics");

And I'd like to register a "before" event handler so that I could, for example, display a login box if a 401 response is returned, or maybe retry if there's a 503 response.

我想注册一个“before”事件处理程序,例如,如果返回401响应,我可以显示一个登录框,或者如果有503响应,可以重试。

I thought that $.ajaxError() is where I would do something like this, but apparently it is only triggered after the event handler.

我认为$. ajaxerror()是我要做的事情,但是显然它是在事件处理程序之后触发的。

UPDATE: OK, here's what I got so far, with the help of @genesis:

更新:好的,这是我到目前为止得到的,在@genesis的帮助下:

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    var success = options.success;
    options.success = function(data, textStatus, jqXHR) {
        // override success handling
        if(typeof(success) === "function") return success(data, textStatus, jqXHR);
    };
    var error = options.error;
    options.error = function(jqXHR, textStatus, errorThrown) {
        // override error handling
        if(typeof(error) === "function") return error(jqXHR, textStatus, errorThrown);
    };
});

After doing some testing, it looks like I would also need to override options.complete.

在做了一些测试之后,看起来我还需要重写option .complete。

However, this still doesn't cover all the bases, since you can also attach events directly to the jqXHR object, and changing options won't help in this case.

但是,这仍然不能覆盖所有的基,因为您还可以将事件直接附加到jqXHR对象,在这种情况下,更改选项没有帮助。

Any tips?

任何建议吗?

3 个解决方案

#1


17  

If you want to handle the data coming back from the server before the event handler, use datafilter:

如果您想在事件处理程序之前处理从服务器返回的数据,请使用datafilter:

    jQuery.ajaxSetup({
        dataFilter: function (data, type) {
            //modify the data

            return data;
        }
    });

#2


5  

Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax().

处理自定义Ajax选项或在每个请求发送之前和在$. Ajax()处理之前修改现有选项。

http://api.jquery.com/jQuery.ajaxPrefilter/

http://api.jquery.com/jQuery.ajaxPrefilter/

I bet it works for .load(), too

我打赌它也适用于.load()

#3


0  

Hugo Forte has the correct answer, the only way to intercept an Ajax response before any event handlers are called is to use dataFilter.

Hugo Forte有正确的答案,在任何事件处理程序被调用之前,拦截Ajax响应的唯一方法是使用dataFilter。

I had to use this today to handle redirecting ajax responses on the client side without refactoring the code too much.

我今天不得不使用它在客户端处理重定向ajax响应,而不需要对代码进行过多的重构。

$.ajaxSetup({
    dataFilter: function (data, type) {
        if (data !== "" && data === "NOAUTH") {
            window.location = '/';
        }
        return data;
    }
});

#1


17  

If you want to handle the data coming back from the server before the event handler, use datafilter:

如果您想在事件处理程序之前处理从服务器返回的数据,请使用datafilter:

    jQuery.ajaxSetup({
        dataFilter: function (data, type) {
            //modify the data

            return data;
        }
    });

#2


5  

Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax().

处理自定义Ajax选项或在每个请求发送之前和在$. Ajax()处理之前修改现有选项。

http://api.jquery.com/jQuery.ajaxPrefilter/

http://api.jquery.com/jQuery.ajaxPrefilter/

I bet it works for .load(), too

我打赌它也适用于.load()

#3


0  

Hugo Forte has the correct answer, the only way to intercept an Ajax response before any event handlers are called is to use dataFilter.

Hugo Forte有正确的答案,在任何事件处理程序被调用之前,拦截Ajax响应的唯一方法是使用dataFilter。

I had to use this today to handle redirecting ajax responses on the client side without refactoring the code too much.

我今天不得不使用它在客户端处理重定向ajax响应,而不需要对代码进行过多的重构。

$.ajaxSetup({
    dataFilter: function (data, type) {
        if (data !== "" && data === "NOAUTH") {
            window.location = '/';
        }
        return data;
    }
});