jQuery - 设置Ajax处理程序优先级

时间:2012-01-16 13:23:57

标签: javascript jquery ajax

实际上问题就像主题所说的那样简单。是否有任何方法可以为不同的ajax处理程序提供更高/更低的优先级(这意味着它们将在之前触发)?

我的意思是什么?好吧,我必须处理一个相当庞大的网络应用程序。大量的Ajax请求在不同的模块中被触发。现在,我的目标是实现一个简单的会话超时机制。每个请求都将当前session-id作为参数发送,如果session-id不再有效,我的后端脚本将返回带有自定义响应标头集的请求(值为uri)。

所以我基本上就是这样

window.jQuery && jQuery( document ).ajaxComplete(function( event, xhr, settings ) {
    var redirectto = xhr.getResponseHeader( 'new_ajax_location' );
    if( redirectto ) {
        location.href = redirectto;
    }
});

这确实像魅力一样,但我的问题是这个全局ajax事件实际上需要在100%的时间内首先被触发,但事实并非如此。其中一些原始的ajax-requests处理程序会因为丢失或意外的数据而抛出错误,在这种情况下,全局处理程序永远不会被执行。

现在,如果我不需要遍历每个请求处理程序并使其对无效会话数据响应的故障保护,我会很高兴。我更喜欢在某个特定的地方做这份工作。但是,如何确保我的全局处理程序首先执行?

4 个答案:

答案 0 :(得分:1)

如果我理解正确,您希望在各处添加自己的回调到json请求。你可以使用ajaxPrefilter钩子。

    $.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
        options.complete = function (jqXHR2, settings) {
            var redirectto = jqXHR2.getResponseHeader( 'new_ajax_location' );
            if( redirectto ) {
                location.href = redirectto;
            }
        }
    });

您还可以更改其中的选项,将session-id添加到请求参数。

答案 1 :(得分:0)

jQuery允许你“修补”它的方法,例如.post / .ajax。

您可以修补相应的方法,以便在您的代码想要调用之前始终触发特殊的AJAX事件。

这是一些“伪jQuery代码”,可以帮助您入门。我怀疑它是否有效,但它展示了基本概念,它应该让你开始。

(function( $ ){
    var originalPost = $.post;
    var calledSpecialOne = false;
    $.post = function(url, data, success, dataType) {
        if (!calledSpecialOne) {
            originalPost( ... your special AJAX query ... ).then( function() {
            originalPost(url, data, success, dataType);
            }
            calledSpecialOne = true;
        } else {
            originalPost(url, data, success, dataType);
        }
    }
})( jQuery );

以上是基于其他一些不相关的代码我已经测试,这使$ .each()适用于未定义/ null数组:

(function($){
    var originalEach = $.each;
    $.each = function(collection, callback) {
        return collection? originalEach(collection, callback) : [];
    }
 })(jQuery);

请注意,许多公开的函数也是由jQuery在内部调用的,所以要非常谨慎地使用这个技巧;你可能会破坏jQuery的不同部分或导致其他麻烦。 在AJAX函数的情况下,您应该只修补最里面的函数,以防止无限递归。 (到目前为止,我还没有发现$ .each()补丁的任何副作用。)

答案 2 :(得分:0)

我不确定这是否与你的意思相符,但我认为无论如何我可能还需要它。

它修补jQuery的ajax函数以接受具有属性priority的对象。如果没有设置优先级,则其优先级变为1(最高优先级0)。如果有优先权,它会做两件事之一。如果优先级大小为5,则检查是否调用了具有先前优先级的ajax调用(在本例中为4)。如果没有,它会将它添加到具有该优先级的ajax调用数组(在本例中为5)。如果已调用先前的优先级,则它会正常调用请求。当使用优先级调用请求时,它会调用具有下一个最高优先级的任何传出请求。

换句话说,如果没有优先级,它会等待优先级0,如果有优先级,它会等待低于它的优先级被调用。如果您希望立即发送没有优先权的电话,请注释掉我说的default action?

评论。
 (function( $ ){
        var oldAjax=$.ajax;
        var outgoing=[];
        var sent=[];
        $.ajax=function(url, settings) {
            var pr = (typeof url==='object'?url:settings).priority;
            pr = pr===undefined ? 1 : pr; // default action?
            if(pr!==undefined){
                if(pr==0 || sent[pr-1]!==undefined){
                    oldAjax(url,settings);
                    sent[pr]=true;
                    if(outgoing[pr]){
                        var rq=outgoing[pr].splice(0,1)[0];
                        $.ajax(rq[0],rq[1]);
                    }
                    if(outgoing[pr+1]){
                        var rq=outgoing[pr+1].splice(0,1)[0];
                        $.ajax(rq[0],rq[1]);
                    }
                }
                else{
                    if(outgoing[pr]!==undefined){
                        outgoing[pr].push([url,settings]);
                    }
                    else{
                        outgoing[pr]=[[url,settings]];
                    }
                }
            }
            else{
                oldAjax(url, settings);
            }
        };
    })( jQuery );

getpost的修补程序。您必须包含这些额外的参数,或者自己更改这些参数以使优先级处理postget请求。这是直接来自jQuery 1.7,除了额外的参数,以及我添加注释的两行。

    jQuery.each( [ "get", "post" ], function( i, method ) {
    jQuery[ method ] = function( url, data, callback, type, priority ) {
        // shift arguments if data argument was omitted
        if ( jQuery.isFunction( data ) ) {
            priority = type; // my change
            type = type || callback;
            callback = data;
            data = undefined;
        }

        return jQuery.ajax({
            type: method,
            url: url,
            data: data,
            success: callback,
            dataType: type,
            priority: priority // my change
        });
    };
});

我在此处设置了一个示例:http://jsfiddle.net/tk39z/

我实际上创建了一些针对谷歌的ajax请求,因此您可以查看Chrome中的网络面板以查看请求。

答案 3 :(得分:0)

我最近实现的功能非常类似于我认为您正在寻找的功能。

我在服务器端设置了一个过滤器来测试有效的会话,如果没有,则返回401错误和自定义状态文本,以获取更具体的错误详细信息。

我对这些页面的ajax调用是使用'success'属性在普通约定中编写的。

对于出现错误的情况,我在错误函数中添加了一个全局回调函数,用于测试特定错误并相应地重定向。如:

$( document ).ajaxError(function(e, xhr) {
    var redirectto = xhr.getResponseHeader( 'new_ajax_location' );
    if( redirectto ) {
        location.href = redirectto;
    }
});