在全局范围内扩展jQuery ajax成功事件

6

我正在尝试创建一个全局处理程序,在ajax成功回调之前调用。我的应用程序中有很多ajax调用,如果出现错误,我会返回一个特定的结构,因此我需要在success运行之前运行某些内容,以检查响应数据是否包含像1/0这样的错误代码位。

示例响应:

{"code": "0", "message": "your code is broken"}

或者

{"code": "1", "data": "return some data"}

我无法在jQuery中找到一个开箱即用的方法来做到这一点,查看了预过滤器、ajaxSetup和其他可用的方法,但它们没有完全实现,我能想到的最好的方法是对ajax方法进行一些小的修改:

var oFn = $.ajax;

$.ajax = function(options, a, b, c)
{
    if(options.success)
    {
        var oFn2 = options.success;

        options.success = function(response)
        {
            //check the response code and do some processing
            ajaxPostProcess(response);

            //if no error run the success function otherwise don't bother
            if(response.code > 0) oFn2(response);
        }
    }

    oFn(options, a, b, c);
};

我已经使用了一段时间,它能正常工作,但想知道是否有更好的方法来完成它,或者jQuery文档中有我错过的内容。


4
听起来像是“鸭子打击”(duck punching),具体解释请见链接:http://paulirish.com/2010/duck-punching-with-jquery/。 - qwertymk
返回200状态的错误信息是完全错误的。将HTTP状态设置为正确的错误代码(4xx / 5xx),并使用jQuery AJAX“error”处理程序。 - Phil
@Phil 验证错误怎么处理?返回4xx或5xx似乎太笼统了。 - Joseph
@qwertymk 我想这基本上就是我所做的,尽管我更喜欢他们处理旧函数的方式:"return _old.apply(this,arguments);" - Rob
@Rob,我点赞你的问题,因为你的解决方案已经足够好了。 - Wilson Freitas
5个回答

12

您可以自己构建AJAX处理程序,而不是使用默认的ajax:

var ns = {};
ns.ajax = function(options,callback){ 
    var defaults = {              //set the defaults
        success: function(data){  //hijack the success handler
            if(check(data)){       //checks
                callback(data);   //if pass, call the callback
            }
        }
    };
    $.extend(options,defaults);  //merge passed options to defaults
    return $.ajax(options);             //send request
}

那么,与其使用 $.ajax 调用,你现在可以使用如下方法:

ns.ajax({options},function(data){
    //do whatever you want with the success data
});

3
回答很好,但有一个问题。有时候像 Backbone.js 这样的第三方库会使用 $.ajax,因此这个解决方案在这些情况下不起作用。 - Wilson Freitas
@WilsonFreitas:为什么对于那些情况它不起作用?Backbone是否修改了原始的$.ajax函数?否则我看不出有什么问题。 - stan
@StanislavPalatnik OP想要的是修改原始的AJAX函数,以便一切使用它的内容都得到自定义配置。我的解决方案只是创建一个新的带有自定义配置的函数,OP可以在他的应用程序中全局使用它,但不能用于其他库。 - Joseph

5

这个解决方案使用鸭子打补丁技术,透明地为每个$.ajax()调用添加了一个自定义的成功处理程序。

(function() {
    var _oldAjax = $.ajax;
    $.ajax = function(options) {
        $.extend(options, {
            success: function() {
                // do your stuff
            }
        });
        return _oldAjax(options);
     };
})();

一件事:我不得不将其更改为 options = $.extend(...) 才能使其工作。它没有通过引用获取 options - Supun Kavinda

1

这里有几个建议:

var MADE_UP_JSON_RESPONSE = {
    code: 1,
    message: 'my company still uses IE6'
};

function ajaxHandler(resp) {
    if (resp.code == 0) ajaxSuccess(resp);
    if (resp.code == 1) ajaxFail(resp);
}

function ajaxSuccess(data) {
    console.log(data);
}

function ajaxFail(data) {
    alert('fml...' + data.message);
}

$(function() {

    // 
    // setup with ajaxSuccess() and call ajax as usual
    //
    $(document).ajaxSuccess(function() {
        ajaxHandler(MADE_UP_JSON_RESPONSE);
    });

    $.post('/echo/json/');

    // ----------------------------------------------------
    //             or
    // ----------------------------------------------------

    // 
    // declare the handler right in your ajax call
    //
    $.post('/echo/json/', function() {
        ajaxHandler(MADE_UP_JSON_RESPONSE);
    });
});​

工作中:http://jsfiddle.net/pF5cb/3/


嗯,问题在于我有大约100个Ajax调用,每个都有一个"success"代码,在响应返回良好代码时运行。 我必须去每个成功函数并包裹这个代码。 我更喜欢在成功函数中只保留清晰的代码,而不让开发团队担心这些东西的包装。它们只需要工作就可以了,至少这是我的目标。 - Rob
我提供的 ajaxHandler 函数是全局的。如果您使用 ajaxSuccess() 选项,只需要声明一次即可。 - Terry
是的,但我的成功函数并不完全相同,其中许多函数会在成功的ajax请求上执行不同的操作。 - Rob
@Rob:你考虑过使用complete函数吗? - Amyth

0

这是您调用ajax方法的代码

 function getData(newUrl, newData, callBack) {
           $.ajax({
               type: 'POST',
               contentType: "application/json; charset=utf-8",
               url: newUrl,
               data: newData,
               dataType: "json",

               ajaxSuccess: function () { alert('ajaxSuccess'); },
               success: function (response) {
                   callBack(true, response);
                   if (callBack == null || callBack == undefined) {
                       callBack(false, null);
                   }
               },
               error: function () {
                   callBack(false, null);
               }
           });
       }

然后回调成功或方法成功

$(document).ajaxStart(function () {
               alert('ajax ajaxStart called');
           });
           $(document).ajaxSuccess(function () {
               alert('ajax gvPerson ajaxSuccess called');
           });

$(document).ajaxSuccess(function () { alert('ajax gvPerson ajaxSuccess called'); }); - hemant pawar

0

这是最基本的例子:

$.ajaxSetup({
    success: function(data){  
        //default code here
    }
});

随意查看$.ajaxSetup()文档


1
它说:“为未来的Ajax请求设置默认值。不建议使用它。 - acme

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接