处理Datatables中的会话超时(使用服务器端数据源处理)

时间:2011-10-05 09:09:21

标签: javascript jquery struts datatables struts-1

我有一个由服务器端Ajax数据源支持的数据表格式(它在后端使用struts操作来处理请求,获取数据并发送JSON响应)。 服务器端操作需要以身份验证模式运行,即需要有活动会话。

在Datatables中处理会话超时错误的最佳方法是什么?目前它只显示一个JSON格式错误,这不是用户的最佳选择。出于显而易见的原因(兼容性,未来的可维护性等),我不想去更改数据表代码。有没有一种处理错误的巧妙方法?

我正在考虑在JSON响应中嵌入错误消息,但在前端流程中拦截它的最佳位置在哪里?

编辑:我认为进行此类后期处理的最佳位置是fnServerData,我是否正确?

4 个答案:

答案 0 :(得分:3)

我会回复一个包含某种错误代码的JSON响应。要处理它,您需要定义fnServerData,因为您已经推测。但是,出于这个原因,我会在使用错误回调之前强烈考虑用例:

错误只是获取资源的任何问题,并使用状态代码。假设会话在服务器上终止。用户请求数据,服务器发回500错误。错误回调说,“好吧,那很糟糕。让我们重定向到登录页面。”一切都很好。

然而......用户提出请求。无论出于何种原因(大数据集,网络条件),请求都需要一点时间。同时,用户决定导航到另一个页面,中断呼叫响应循环。没有响应,错误回调被触发,用户被重定向到登录页面(或错误回调中设置的任何功能)。

问题是没有我所知道的状态代码(我很想知道!我不介意错在这里!)因为“会话已经过期”才能捕获和处理。

我不是说你“不应该”或“不能”使用错误回调。但该功能必须考虑会话到期以外的错误。您可能需要根据状态代码进行不同的处理。如果你的功能优雅地处理所有这些情况,太棒了!在一个应用程序中,我们确实重定向到登录页面,并且错误回调通常会因误报而跳闸,将用户错误地转储到登录页面。对于“会话已过期”的情况,我们通过JSON消息在成功回调中捕获它。

[在Dave的优秀评论之后更新:]如果你的服务器返回一个有用的服务器错误(401,403,550或你的场景中有意义的话),那么在.ajax()调用中使用带有statusCode参数的fnServerData(那是满口!)也会起作用。我认为这是相同的工作量:通过您已经编写的方法返回JSON,或者通过您应该有权访问的方法返回状态错误。选择哪一个对你有用。

答案 1 :(得分:2)

以下技术对我有用......我知道回复为时已晚,但希望代码可以帮助某人

1)检查控制器(MVC)中的会话是否超时并返回     应在客户端处理的状态代码

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

2)在客户端使用jQuery global ajax Error,它可以捕获所有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);
});

答案 2 :(得分:1)

即使已经有很长一段时间了,我已经问过这个问题,如果有人需要,我会发布我的解决方案。

此解决方案适用于JQuery Datatables的1.10.16版。

经过一段时间的挖掘后,我发现了会话到期时显示警报的功能。这是:

/**
     * 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即可。 我承认这不是最干净的代码,但它有效。

答案 3 :(得分:0)

我使用bill martino的答案在这里完成了: 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"}