【问题标题】:JQuery AJAX - Filter before .done()JQuery AJAX - 在 .done() 之前过滤
【发布时间】:2016-08-17 21:09:20
【问题描述】:

我的应用程序有很多 AJAX 调用,每个调用都返回一个 JSON 响应。我没有验证每个 .done() 调用中的数据,而是尝试压缩代码。

我们目前所拥有的

$.ajax({
    url: 'test',
    type: 'GET',
    data: {
        _token: token
    },
    dataFilter: function(jsonResponse) {
        return isValidJson(jsonResponse);
    }
}).done(function(jsonResponse) {
    // do things
});

isValidJson(jsonResponse) {
    try {
        var parsedJson = $.parseJSON(jsonResponse);

        if (parsedJson.error == 1) {
            notificationController.handleNotification(parsedJson.message, 'error');

            return false;
        }
    } catch (err) {
        notificationController.handleNotification('A server-side error occured. Try refreshing if the problem persists.', 'error');

        return false;
    }

    return jsonResponse; // Have to return the original data not true
}

预期的行为是如果dataFilter返回false,它会触发.fail(),如果它返回true,它会继续.done()。相反,它只是继续 .done() 并返回 isValidJson() 的结果。

还有没有办法让 .fail() 做一些标准的事情,比如向用户发送通知,而不必将其放在每个 AJAX 调用下?

【问题讨论】:

  • 没有。 “一个用于处理 XMLHttpRequest 的原始响应数据的函数。这是一个用于净化响应的预过滤函数。您应该返回净化后的数据”。因此,如果 json 检查是否正常,则不应返回 TRUE 或 FALSE。你的策略是错误的
  • @RoyiNamir 谢谢你。您是否知道为所有 AJAX 调用过滤 .done() 之外的数据的正确方法?我应该扩展一些东西吗?
  • 你试过这个 var jxhr = $.ajax(dataFilter : function() {jxhr.abort()}); ?

标签: javascript jquery ajax


【解决方案1】:

最简单的方法是创建 $.ajax 的简写,通过扩展它。

扩展 AJAX 调用

jQuery.extend({
    myAjax: function(params){
        // Here we can modify the parameters and override them e.g. making 'error:' do something different
        // If we want to add a default 'error:' callback
        params.error = function() {
            console.log('its failed');
        };

        // or you can specify data parse here
        if (params.success && typeof params.success == 'function') {
            var successCallback = params.success;
            var ourCallback = function(responseJson) {
                if (isValidJson(responseJson)) { // Validate the data
                    console.log('The json is valid');
                    successCallback(responseJson); // Continue to function
                } else {
                    console.log('The json is not valid');
                }
            }

            params.success = ourCallback;
        }

        return $.ajax(params);
    }
});

现在,每次您想在应用程序中进行 AJAX 调用时,都不要使用 $.ajax({})。相反,您使用 $.myAjax({});

示例

$.myAjax({
    url: 'domain.com',
    type: 'GET',
    success: function(data) {
       // Do what you'd do normally, the data here is definitely JSON.
    },
    error: function(data) {}
});

而且这个特殊功能会以同样的方式处理所有错误,无需每次都编写那些验证器。

【讨论】:

  • 嗯,有两个回调。 $.ajax 中的 error 和 xhr 对象中的 fail。我试图设置 $.ajax 的失败。编辑了你的小提琴,现在它可以工作了。 jsfiddle.net/drnuz676/6
【解决方案2】:

尝试这样做(Not tested):

var jxhr = $.ajax({
    url: 'test',
    type: 'GET',
    data: {
        _token: token
    },
    dataFilter: function(jsonResponse) {        
        if (!isValidJson(jsonResponse)) {
           jxhr.abort();
        }
        return jsonResponse;
    }
}).done(function(jsonResponse) {
    // do things
});

【讨论】:

  • 您违反了“关注点分离”原则。为什么 A 的行为应该因为 B 的行为而返回 false ? A 的操作应该返回 true ,稍后,如果您愿意,为 B 的操作返回 false。
  • @Kison .abort() 仍然调用 .done()。如果这确实有效,是否有办法自动将其应用于所有未来的 ajax 请求?
  • @RoyiNamir 你是对的,需要考虑更正确的方法如何做到这一点
  • @TobyMellor,全局ajax回调ajaxSuccess怎么样?
【解决方案3】:

使用此策略 - 您违反了“关注点分离”策略。

Ajax 应该根据其操作来解决或拒绝。不根据响应是否为 JSON。

一个可能的解决方案:(当然还有其他解决方案)

function GetSanitized(d) {
    return d.then(function(a) {
            if (a.indexOf('{') > -1) //check if json ( just for example)
                return $.Deferred().resolve(JSON.parse(a)); //return object
            else
                return $.Deferred().reject(a); //reject
        },

        function() {
            return $.Deferred().reject("ajax error"); //ajax failed
        }

    );
}

var ajax = $.Deferred();

GetSanitized(ajax) .then(function (a){alert(" Json p's value is "+a["p"]);},function (a){alert("Error"+a);});


ajax.resolve("{\"p\":2}"); //simulate ajax ok , valid json 
//ajax.resolve("\"p\":2}"); //simulate ajax ok , invalid json 
//ajax.reject("\"p\":2}"); //simulate ajax bad , valid json 

http://jsbin.com/vozoqonuda/2/edit

【讨论】:

    猜你喜欢
    • 2019-09-10
    • 2014-08-14
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 2016-09-25
    • 1970-01-01
    相关资源
    最近更新 更多