授权过期后AJAX操作跳转到登录页的一种全局处理方式
2013-10-22 20:34
309 查看
前两天园友JustRun分享了一篇 《菜鸟程序员之Asp.net MVC Session过期异常的处理》博文,正好自己前段时间被安排处理过这个问题,发现JustRun的方法有一点点可优化的地方,就评论里提了一下思路。今天看到有园友好像没明白我说的意思,所以就决定写此博文简单介绍一下,不太适合老鸟们观看,权当是给新人写的一点经验分享。
然后就是前端部分的处理了,前端使用$.ajaxSetup的statusCode参数来统一处理,在模板页面中,写入以下代码:
好了,所有的代码都完成了,下面进行简单的测试一下,服务端写了两个Action(这两个Action需要用上面写的授权模块),一个返回Time,一个返回Guid:
页面上写了两个ajax请求,分别请求以上两个Action:
当然还要添加登录退出功能(这块代码就不贴了,见源码吧),在授权有效期内,运行效果如下:
这时,如果我们再打开一个新页面点退出(或直接把cookie删掉),再点击上面的GetTime或GetGuid按钮发送ajax请求,结果如下:
OK,达到预期效果。如有更优雅的处理方式,也请大家分享。DEMO使用VS2010+MVC3开发,源码请点此下载。
什么问题
通常在对一些敏感数据进行操作前,都要进行身份认证。如果没有通过认证,则重定向(跳转)到登录页面。但这种服务端重定义的方式,对ajax请求却没有任何作用。本文就是给出一种全局处理方式,来解决这类问题。如何解决
思路很简单,就是当授权过期后,针对ajax请求返回一个特定的标识,然后前端通过识别该标识,来跳转到登录页面。而且最好不用在每处ajax请求的代码中都加上对这种标识判断,即要能全局处理。所以目标就落在了jQuery.ajax的全局配置($.ajaxSetup)上了,通过查看API,发现statusCode参数用来做这件事再好不过了,而且重要的是,即使ajax代码中禁用了全局配置(global:false),关于statusCode的配置都仍然有效(这点对我们之前项目中来说很重要,因为有很多的ajax都禁用了全局的遮罩效果)。代码演示
原理清楚了,代码实现起来也就并不复杂了,首先在服务端需要针对ajax请求,返回特殊的标识。这里重写了MVC自带的授权模块的HandleUnauthorizedRequest逻辑,未通过授权时,如果是ajax请求,则返回一个HttpStatusCode,这个值尽量不要与现有的[b]HTTP状态码重复[/b],我这里用的是499,然后将登录页的地址写到响应流中(这里可以根据需要返回其他信息)。自定义的授权模块代码如下:public class WebAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.Result = new HttpStatusCodeResult(499); //尽量不要与现有的Http状态码冲突 filterContext.HttpContext.Response.Write(FormsAuthentication.LoginUrl); //可以根据需要返回其他信息 } else { base.HandleUnauthorizedRequest(filterContext); } } }
然后就是前端部分的处理了,前端使用$.ajaxSetup的statusCode参数来统一处理,在模板页面中,写入以下代码:
<script type="text/javascript"> $.ajaxSetup({ statusCode: { 499: function (data) { alert(data.responseText); //window.location.href = data.responseText; } } }); </script>
好了,所有的代码都完成了,下面进行简单的测试一下,服务端写了两个Action(这两个Action需要用上面写的授权模块),一个返回Time,一个返回Guid:
[WebAuthorize] public ActionResult GetTime() { return Content(DateTime.Now.ToString()); } [WebAuthorize] public ActionResult GetGuid() { return Content(Guid.NewGuid().ToString()); }
页面上写了两个ajax请求,分别请求以上两个Action:
<input id="Button1" type="button" value="GetTime" /> <input id="Button2" type="button" value="GetGuid" /> <script type="text/javascript"> $("#Button1").click(function () { $.get("/Home/GetTime", function (data) { $("body").append(data + '<br/>'); }); }); $("#Button2").click(function () { $.ajax({ url: '/Home/GetGuid', global: false, //禁用全局,不影响$.ajaxSetup中的statusCode success: function (data) { $("body").append(data + '<br/>'); } }); }); </script>
当然还要添加登录退出功能(这块代码就不贴了,见源码吧),在授权有效期内,运行效果如下:
这时,如果我们再打开一个新页面点退出(或直接把cookie删掉),再点击上面的GetTime或GetGuid按钮发送ajax请求,结果如下:
OK,达到预期效果。如有更优雅的处理方式,也请大家分享。DEMO使用VS2010+MVC3开发,源码请点此下载。
相关文章推荐
- jQuery ajax全局函数处理session过期后的ajax跳转问题
- 基于jquery的全局ajax函数处理session过期后的ajax操作
- 处理jquery的ajax请求session过期跳转到登录页面
- ajax前置处理实现异步请求session过期时跳转登录页面
- jQuery ajax全局函数处理session过期后的ajax跳转问题
- ajax请求 session过期跳转首页的两种处理方式
- ajax请求 session过期跳转首页的两种处理方式
- 重写ajax方法实现异步请求session过期时跳转登录页面
- ajax提交session超时跳转页面使用全局的方法来处理
- 处理事件的方式:两种类的覆盖处理(自己管理,覆盖专用事件函数;自己统一管理,覆盖QWidget::Event通用函数),一种对象的处理(父控件统一管理,即安装过滤器),两种全局处理(QCoreApplication安装过滤器;覆盖notify方法)
- Struts 通过拦截器实现登录后跳转到登录前页面 处理普通Http请求和Ajax请求时拦截配置
- flex(替代session过期)用户长时间不操作要求重新登录的处理
- 关于CAS服务端登录前ajax访问后台方法被拦截的配置-另外一种实现方式
- 重写ajax方法实现请求session过期时跳转登录页面
- 【Java】关于ajax的session过期跳转登录
- 重写ajax方法实现异步请求session过期时跳转登录页面(转)
- session过期,处理ajax请求,使其重新登录
- 当 jquery 发送 ajax 请求的时候遇到服务端session过期超时返回 302 跳转登陆页面的时候怎么办的处理方法
- ajax提交session超时跳转页面使用全局的方法来处理
- ajax提交session超时跳转页面使用全局的方法来处理