18

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.

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.

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

UPDATE: OK, here's what I got so far, with the help of @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.

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.

Any tips?

itsadok
  • 28,822
  • 30
  • 126
  • 171

3 Answers3

25

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

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

            return data;
        }
    });
Hugo Forte
  • 5,718
  • 5
  • 35
  • 44
8

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

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

I bet it works for .load(), too

genesis
  • 50,477
  • 20
  • 96
  • 125
  • I might be misreading the original question or the jQuery docs, but it looks to me like `ajaxPrefilter` is going to intervene **before** the request is sent and @itsadok wants something to intervene **after** the request is sent and the response is received but before it gets processed. – Rick Liddle Aug 31 '11 at 11:47
  • @Rick, the trick is to override options.success and options.error. I'm still working it out, though. – itsadok Aug 31 '11 at 11:58
  • @itsadok, wouldn't `ajaxComplete()` be the better place to catch it? Or is that too late in the cycle? I'll admit that jQuery is not my strong suit... – Rick Liddle Aug 31 '11 at 12:08
  • 1
    `ajaxPrefilter` appears to work for my use case, where I want to suppress the local error handler for http status code 401 (unathenticated) responses in favor of a global one. ` $.ajaxPrefilter(function (options, originalOptions, jqXHR) { var error = options.error; options.error = function (jqXHR, textStatus, errorThrown) { if (typeof (error) === "function" && jqXHR.status != 401) return error(jqXHR, textStatus, errorThrown); }; });` – Nathan Oct 17 '12 at 20:49
  • @itsadok - How did you get on with overriding the specific instance handlers without creating others? – Nick Middleweek Mar 24 '16 at 16:54
1

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

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

$.ajaxSetup({
    dataFilter: function (data, type) {
        if (data !== "" && data === "NOAUTH") {
            window.location = '/';
        }
        return data;
    }
});
Shahin Dohan
  • 6,149
  • 3
  • 41
  • 58