处理Datatables中的会话超时(使用服务器端数据源处理)
我有一个由服务器端Ajax数据源支持的数据表格式(它在后端使用struts操作来处理请求,获取数据并发送JSON响应)。 服务器端操作需要以认证模式运行,即需要有活动会话。
在Datatables中处理会话超时错误的最佳方法是什么? 目前它只显示一个JSON格式错误,这不是用户的最佳选择。 出于显而易见的原因(兼容性,未来的可维护性等),我不想去更改数据表代码。 有一种处理错误的巧妙方法吗?
我正在考虑在JSON响应中嵌入错误消息,但在前端流程中拦截它的最佳位置是哪里?
编辑:我认为进行此类后期处理的最佳位置是fnServerData,我是否正确?
我会回火一个包含某种错误代码的JSON响应。 要处理它,您需要定义fnServerData,如您所推测的那样。 但是,出于这个原因,我会在使用错误回调之前强烈考虑用例:
错误只是获取资源的任何问题,并使用状态代码。 假设会话在服务器上终止。 用户请求数据,服务器发回500错误。 错误回调说,“好吧,这很糟糕。让我们重定向到登录页面。” 一切都很好。
但是……用户提出请求。 无论出于何种原因(大数据集,网络条件),请求都需要一点时间。 同时,用户决定导航到另一个页面,中断呼叫响应循环。 如果没有响应,则错误回调被触发,用户被重定向到登录页面(或错误回调中设置的任何function)。
问题是没有我所知道的状态代码(我很想知道!我不介意错在这里!)因为“会话已经过期”以便捕获和处理。
我不是说你“不应该”或“不能”使用错误回调。 但该function必须考虑会话到期以外的错误。 您可能需要根据状态代码进行不同的处理。 如果你的function优雅地处理所有这些情况,太棒了! 在一个应用程序中,我们确实重定向到登录页面,并且错误回调通常会因误报而跳闸,将用户错误地转储到登录页面。 对于“会话已过期”的情况,我们通过JSON消息在成功回调中捕获它。
[在Dave的优秀评论之后更新:]如果您的服务器返回有用的服务器错误(401,403,550或在您的方案中有意义的任何内容),那么在.ajax()调用中使用带有statusCode参数的fnServerData(这是一个满口! )也会起作用。 我认为这是相同的工作量:通过您已经编写的方法返回JSON,或者通过您应该已经访问过的方法返回状态错误。 选择哪一个对你有意义。
以下技术对我有用……我知道回复为时已晚,但希望代码可以帮助某人
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); });
尽管已经有很长一段时间以来我已经问过这个问题,但是如果有人需要的话我会发布我的解决方案。
此解决方案适用于JQuery Datatables的1.10.16版。
经过一段时间的挖掘后,我发现了会话到期时显示警报的function。 这里是:
/** * 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即可。 我承认这不是最干净的代码,但它有效。
我使用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"}
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.点击按钮调用按钮function获取错误..输入function中的一行
$.fn.dataTable.ext.errMode = 'none';
像一个例子
function ChangeUrl(){ $.fn.dataTable.ext.errMode = 'none'; product_table.fnStandingRedraw(); }