授权过期后AJAX操作跳转到登录页的一种全局处理方式_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 授权过期后AJAX操作跳转到登录页的一种全局处理方式

授权过期后AJAX操作跳转到登录页的一种全局处理方式

 2013/10/22 22:55:16  何苦丶  博客园  我要评论(0)
  • 摘要:前两天园友JustRun分享了一篇《菜鸟程序员之Asp.netMVCSession过期异常的处理》博文,正好自己前段时间被安排处理过这个问题,发现JustRun的方法有一点点可优化的地方,就评论里提了一下思路。今天看到有园友好像没明白我说的意思,所以就决定写此博文简单介绍一下,不太适合老鸟们观看,权当是给新人写的一点经验分享。什么问题通常在对一些敏感数据进行操作前,都要进行身份认证。如果没有通过认证,则重定向(跳转)到登录页面。但这种服务端重定义的方式,对ajax请求却没有任何作用
  • 标签:Ajax 方式 操作 授权 全局

前两天园友JustRun分享了一篇 《菜鸟程序员之Asp.net MVC Session过期异常的处理》博文,正好自己前段时间被安排处理过这个问题,发现JustRun的方法有一点点可优化的地方,就评论里提了一下思路。今天看到有园友好像没明白我说的意思,所以就决定写此博文简单介绍一下,不太适合老鸟们观看,权当是给新人写的一点经验分享。

什么问题

通常在对一些敏感数据进行操作前,都要进行身份认证。如果没有通过认证,则重定向(跳转)到登录页面。但这种服务端重定义的方式,对ajax请求却没有任何作用。本文就是给出一种全局处理方式,来解决这类问题。

如何解决

思路很简单,就是当授权过期后,针对ajax请求返回一个特定的标识,然后前端通过识别该标识,来跳转到登录页面。而且最好不用在每处ajax请求的代码中都加上对这种标识判断,即要能全局处理。所以目标就落在了jQuery.ajax的全局配置($.ajaxSetup)上了,通过查看API,发现statusCode参数用来做这件事再好不过了,而且重要的是,即使ajax代码中禁用了全局配置(global:false),关于statusCode的配置都仍然有效(这点对我们之前项目中来说很重要,因为有很多的ajax都禁用了全局的遮罩效果)。

代码演示

原理清楚了,代码实现起来也就并不复杂了,首先在服务端需要针对ajax请求,返回特殊的标识。这里重写了MVC自带的授权模块的HandleUnauthorizedRequest逻辑,未通过授权时,如果是ajax请求,则返回一个HttpStatusCode,这个值尽量不要与现有的HTTP状态码重复,我这里用的是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);
            }
        }
    }

然后就是前端部分的处理了,前端使用$.ajaxSetupstatusCode参数来统一处理,在模板页面中,写入以下代码:

    <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开发,源码请点此下载

发表评论
用户名: 匿名