jQuery-установить приоритет обработчика Ajax

на самом деле вопрос так прост, как тема говорит. Есть ли способ дать различным обработчикам ajax более высокий / более низкий приоритет (что означает, что они будут стрелять раньше) ?

что я имею в виду? Ну, мне приходится иметь дело с довольно огромным веб-приложением. Тонны запросов Ajax запускаются в разных модулях. Теперь моя цель-реализовать простой механизм тайм-аута сеанса. Каждый запрос отправляет текущий идентификатор сеанса в качестве параметра, если идентификатор сеанса больше не действителен, мой сервер скрипт возвращает запрос с пользовательским набором заголовков ответов (значение-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-запросов выдадут ошибку из-за отсутствия или неожиданных данных, в этом случае глобальный обработчик никогда не будет выполнен.

теперь, Я был бы рад, если бы мне не нужно было проходить через каждый обработчик запросов и делать его отказоустойчивым для недопустимых ответов данных сеанса. Я бы предпочел работать в одном месте. Но как я могу убедиться, что мой глобальный обработчик будет выполняться первым ?

4 ответов


Если я правильно вас понимаю, вы хотите добавить свой собственный обратный вызов в запросы JSON везде. Вы можете использовать крюк ajaxPrefilter.

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

вы также можете изменить параметры, чтобы добавить идентификатор сеанса в параметры запроса.


jQuery позволяет вам "исправлять" его методы, такие как .пост./Аякс.

возможно, вы сможете исправить соответствующие методы, поэтому ваше специальное событие 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 );

вышеуказанное основано на некотором другом, несвязанном, коде I есть проверено, что делает $.каждый () работает для неопределенных / нулевых массивов):

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

обратите внимание, что многие открытые функции также вызываются внутри jQuery, поэтому будьте очень осторожны, используя этот трюк; вы можете сломать другую часть jQuery или вызвать другие проблемы. В случае функций AJAX вы, вероятно, должны исправить только самую внутреннюю функцию, чтобы предотвратить бесконечную рекурсию. (FWIW, я не нашел никаких побочных эффектов для $.каждый () патч до сих пор).


Я не уверен, что это то, что вы имели в виду, но я подумал, что мне это может понадобиться в любом случае.

он исправляет функцию ajax jQuery, чтобы принять объект со свойством 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 );

патчи get и post. Вам придется включить эти дополнительные аргументы или изменить это самостоятельно, чтобы получить приоритет при работе с post и get запросы. Это прямо из 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-запросы, нацеленные на google, поэтому вы можете проверить панель сети в Chrome для просмотра запросов.


недавно я реализовал что-то очень похожее на функциональность, которую, я считаю, вы ищете.

я настраиваю фильтр на стороне сервера для проверки допустимого сеанса и, если нет, возвращаю ошибку 401 с пользовательским текстом состояния для более конкретной детали ошибки.

вызовы ajax, которые я сделал на эти страницы, были написаны в обычном соглашении с использованием атрибута "success".

для ситуаций, когда произошла ошибка, я добавил глобальный обратный вызов функция ошибки, которая будет проверять конкретную ошибку и перенаправлять соответственно. например:

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