admin管理员组

文章数量:1323737

ISSUE

I needed a way to modify all ajax responses in an app before all bound callbacks are triggered.

SOLUTION

Standard ajax events, both global and local do not provide a good way to modify the response before app bound callback are triggered.

The order by which ajax events get triggered is the one indicated in the jquery's ajax event docs i.e.

  • ajaxStart (Global Event)
  • beforeSend (Local Event)
  • ajaxSend (Global Event)
  • success (Local Event)
  • ajaxSuccess (Global Event)
  • error (Local Event)
  • ajaxError (Global Event)
  • plete (Local Event)
  • ajaxComplete (Global Event)
  • ajaxStop (Global Event)

Notice that there is no hook executed after the response gets back from the server but before success/erorr callback are run e.g. a kind of ajaxReturn after ajaxSend but before success|error

The way i hacked this was to use $.ajaxPrefilter which is executed before ajaxStart and to wrap the already bound success/error callbacks in another function which will allow me to modify the options object and thus the returned data.

Below is the utility function that does the wrapping and an example:

var alterResponse = function (opts) {
    var callback = function (options, originalOptions, jqXHR) {
        if (options.url.match(opts.urlMatch)) {
            // Cache original callback.
            var originalSuccess = originalOptions.success || options.success;
            originalOptions.success = options.success = function () {
                // Call wrapper that will modify the response object.
                opts.successWrapper.call(null, options, originalOptions, jqXHR, originalSuccess);
            };
        }
    };
    if (opts.dataTypes) {
        $.ajaxPrefilter(opts.dataTypes, callback)
    }
    else {
        $.ajaxPrefilter(callback);
    }
};

alterResponse({
    urlMatch: /myurl/g, // Filter urls you what to tamper with.
    successWrapper: function (options, originalOptions, jqXHR, originalFn) {
        options.data.customVar = 'customValue';
        originalFn(options, originalOptions, jqXHR);
    }
});

I have to mention i'm using this for testing purposes so i'm not concerned about performance, memory and overhead.

ISSUE

I needed a way to modify all ajax responses in an app before all bound callbacks are triggered.

SOLUTION

Standard ajax events, both global and local do not provide a good way to modify the response before app bound callback are triggered.

The order by which ajax events get triggered is the one indicated in the jquery's ajax event docs i.e.

  • ajaxStart (Global Event)
  • beforeSend (Local Event)
  • ajaxSend (Global Event)
  • success (Local Event)
  • ajaxSuccess (Global Event)
  • error (Local Event)
  • ajaxError (Global Event)
  • plete (Local Event)
  • ajaxComplete (Global Event)
  • ajaxStop (Global Event)

Notice that there is no hook executed after the response gets back from the server but before success/erorr callback are run e.g. a kind of ajaxReturn after ajaxSend but before success|error

The way i hacked this was to use $.ajaxPrefilter which is executed before ajaxStart and to wrap the already bound success/error callbacks in another function which will allow me to modify the options object and thus the returned data.

Below is the utility function that does the wrapping and an example:

var alterResponse = function (opts) {
    var callback = function (options, originalOptions, jqXHR) {
        if (options.url.match(opts.urlMatch)) {
            // Cache original callback.
            var originalSuccess = originalOptions.success || options.success;
            originalOptions.success = options.success = function () {
                // Call wrapper that will modify the response object.
                opts.successWrapper.call(null, options, originalOptions, jqXHR, originalSuccess);
            };
        }
    };
    if (opts.dataTypes) {
        $.ajaxPrefilter(opts.dataTypes, callback)
    }
    else {
        $.ajaxPrefilter(callback);
    }
};

alterResponse({
    urlMatch: /myurl/g, // Filter urls you what to tamper with.
    successWrapper: function (options, originalOptions, jqXHR, originalFn) {
        options.data.customVar = 'customValue';
        originalFn(options, originalOptions, jqXHR);
    }
});

I have to mention i'm using this for testing purposes so i'm not concerned about performance, memory and overhead.

Share Improve this question edited Oct 11, 2012 at 10:06 alexandru.topliceanu asked Oct 10, 2012 at 16:06 alexandru.topliceanualexandru.topliceanu 2,3642 gold badges27 silver badges38 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 10

If you'd like to modify the data ing back from the server before it reaches the event handler, use dataFilter:

    jquery.ajaxSetup({
        dataFilter: function (data, type) {
            //modify your data here

            return data;
        }
    });

You can use any of the global ajax events

$(document).ajaxSuccess(function() {
   alert("An individual AJAX call has pleted successfully");
 });
 //or...
$(document).ajaxComplete(function() {
  alert("ALL current AJAX calls have pleted");
});

//or.. 
$(function() {
$.ajaxSetup({
    plete: function(xhr, textStatus) {
        // will be raised whenever an AJAX request pletes (success or failure)
    },
    success: function(result) {
        // will be raised whenever an AJAX request succeeds
    },
    etc ... you could use any available option
});

});

本文标签: javascriptModify ajax response before any bound callbacks get executedStack Overflow