Обработка тайм-аутов сеанса в таблицах данных (с обработкой источника данных на стороне сервера) - PullRequest
3 голосов
/ 05 октября 2011

У меня есть форма таблицы данных, которая поддерживается серверным источником данных Ajax (который использует действие Struts в серверной части для обработки запроса, извлечения данных и отправки ответа JSON). Операция на стороне сервера должна выполняться в режиме аутентификации, т. Е. Должен быть активный сеанс.

Каков наилучший способ обработки ошибок времени ожидания сеанса в таблицах данных? В настоящее время это просто показывает ошибку форматирования JSON, которая не является лучшим вариантом для пользователя. Я не хочу идти и изменять код данных по очевидным причинам (совместимость, возможность сопровождения в будущем и т. Д.). Есть ли аккуратный способ обработки ошибок?

Я думал о том, как встроить сообщение об ошибке в ответ JSON, но где лучше всего перехватить его во входном потоке?

РЕДАКТИРОВАТЬ: я полагаю, что лучшее место для такой пост-обработки было бы в fnServerData, я прав?

Ответы [ 5 ]

3 голосов
/ 05 октября 2011

Я бы вызвал ответ JSON, содержащий какой-то код ошибки.Чтобы обработать его, вам нужно определить fnServerData, как вы и предполагали.Тем не менее, я бы настоятельно рассмотрел вариант использования перед использованием обратного вызова с ошибкой по этой причине:

Ошибка - это просто любая проблема при извлечении ресурса и использовании кодов состояния.Допустим, сеанс завершается на сервере.Пользователь запрашивает данные, сервер отправляет обратно 500 ошибок.Ошибка обратного вызова говорит: «Ну, это отстой. Давайте перенаправим на страницу входа».Все отлично работает.

Однако ... пользователь делает запрос.По какой-то причине запрос занимает немного времени (большой набор данных, состояние сети).Тем временем пользователь решает перейти на другую страницу, прерывая цикл ответа на вызов.При отсутствии ответа обратный вызов ошибки отключается, и пользователь перенаправляется на страницу входа (или любую другую функцию, установленную в обратном вызове ошибки).

Проблема в том, что нет кода состояния, о котором я знаю(Хотелось бы знать, хотя! Я не против, чтобы я ошибался здесь!), Поскольку «сессия истекла», чтобы получить и обработать.

Я не говорю, что вы «не должны»или "не могу" использовать ошибку обратного вызова.Но функция должна учитывать ошибки, отличные от истечения сеанса.Возможно, вам придется начать обработку по-разному в зависимости от кодов состояния.Если ваша функция элегантно обрабатывает все эти случаи, прекрасно!В одном приложении мы действительно перенаправляем на страницу входа в систему, и функция обратного вызова с ошибкой часто срабатывает из-за ложного срабатывания, неправильно выкидывающего пользователя на страницу входа.В случае «сеанса истек» мы перехватываем его в обратном вызове успеха через сообщение JSON.

[обновлено после превосходных комментариев Дэйва:] Если ваш сервер возвращает полезную ошибку сервера (401, 403,550 или что-то еще, что имеет смысл в вашем сценарии), тогда использование fnServerData с параметром statusCode в вызове .ajax () (это полный рот!) Будет работать так же хорошо.Я думаю, что это тот же объем работы: вернуть JSON с помощью метода, который вы уже написали, или вернуть ошибку состояния с помощью методов, к которым у вас уже должен быть доступ.Выберите, какой из них имеет смысл для вас.

2 голосов
/ 29 декабря 2017

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

1) Проверьте, истекло ли время ожидания сеанса в контроллере (MVC), и верните код состояния, который должен обрабатываться на стороне клиента

if (!Request.IsAuthenticated)
{
    return new HttpStatusCodeResult((HttpStatusCode)302, "Authentication timeout");
}

2) На стороне клиента используйте глобальную ajax Error jQuery, которая перехватывает ошибки всех вызовов ajax. Проверьте код статуса и перенаправьте на страницу входа

$(document).ajaxError(function (event, jqxhr, settings, thrownError) {
   if (jqxhr.status === 302) {
      document.location.href = '/account/login';
   }
});

3) [Необязательно] Отключите предупреждения из таблиц данных и проверьте ошибки в консоли

/*disable datatable warnings*/
$.fn.dataTable.ext.errMode = 'none';

/*display warnings in the console*/
$tblDashboard.on('error.dt', function (e, settings, techNote, message) {
      console.log('An error has been reported by DataTables: ', message);
});
1 голос
/ 23 апреля 2018

Несмотря на то, что с тех пор, как был задан этот вопрос, прошло много времени, я собираюсь опубликовать свое решение, если на всякий случай оно кому-нибудь понадобится.

Это решение применяется к версии 1.10.16 JQuery Datatables.

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

/**
     * Log an error message
     *  @param {object} settings dataTables settings object
     *  @param {int} level log error messages, or display them to the user
     *  @param {string} msg error message
     *  @param {int} tn Technical note id to get more information about the error.
     *  @memberof DataTable#oApi
     */
    function _fnLog( settings, level, msg, tn )
    {
        msg = 'DataTables warning: '+
            (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;

        if ( tn ) {
            msg += '. For more information about this error, please see '+
            'http://datatables.net/tn/'+tn;
        }

        if ( ! level  ) {
            // Backwards compatibility pre 1.10
            var ext = DataTable.ext;
            var type = ext.sErrMode || ext.errMode;

            if ( settings ) {
                _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
            }

            if ( type == 'alert' ) {
                alert( msg );
            }
            else if ( type == 'throw' ) {
                throw new Error(msg);
            }
            else if ( typeof type == 'function' ) {
                type( settings, tn, msg );
            }
        }
        else if ( window.console && console.log ) {
            console.log( msg );
        }
    }

Как вы можете видеть, есть проверка на переменную типа, чтобы увидеть, является ли она функцией. Если это так, то это вызывается. Обратите внимание, что переменная типа получается следующим образом:

var type = ext.sErrMode || ext.errMode;

Итак, я сделал это:

//Check the message and redirect
  $.fn.dataTable.ext.errMode = function (settings, tn, msg) {
    if (msg.indexOf("YourErrorCode") != -1) {
      window.location = "/login";
    }
  }

Просто замените YourErrorCode на то, что вам нужно, и оно будет работать. Я признаю, что это не самый чистый код, но он работает.

0 голосов
/ 27 февраля 2018

1.Используйте этот код на странице получения ошибки ajax. или также использовал файл нижнего колонтитула. Этот код работает в течение тайм-аута сеанса после перенаправления на страницу входа, не получая ошибку ajax.

$(document).ajaxError(function(event, jqxhr, settings, exception) {

if (exception == 'Unauthorized') {
    // Prompt user if they'd like to be redirected to the login page
    window.location = '<?=route("admin.login")?>';

    }
});
function CheckSession() {
    var session = '<%=Session["name"] != null%>';
    //session = '<%=Session["username"]%>';
    if (session == false) {
        window.location = '<?=route("admin.login")?>';
    }
}

setInterval(CheckSession(),500);

2.Нажмите кнопку, вызываемую для функции, в момент получения ошибки. Введите одну строку в функции

 $.fn.dataTable.ext.errMode = 'none';

как один пример

function ChangeUrl(){
        $.fn.dataTable.ext.errMode = 'none';
        product_table.fnStandingRedraw();
    }
0 голосов
/ 11 апреля 2015

Я сделал это, используя ответ Билла Мартино здесь: http://datatables.net/forums/discussion/4377/catch-text-returned-from-server-side-ajax-call

"fnServerData": function ( sSource, aoData, fnCallback ) {
    // get filter ID
    var filter_id = $('#storedFilter_id').val();
    // send filter ID
    aoData.push(
        { "name": "filter_id", "value": $.trim(filter_id) }
    );
    $.getJSON( sSource, aoData, function (json) {
        // check for expired session being returned, if so, send the user back to the login page
        if(json.error == 'expired'){
            document.location.href='index.cfm?fuseaction=login.form';    
        }
        else{
            fnCallback(json)
        }

     });
}

В ответе Ajax Source вы должны вернуть строку Json, например:

{"error": "expired"}
...