asp.net AJAX 调用时会话超时

mzsu5hc0  于 2023-01-06  发布在  .NET
关注(0)|答案(6)|浏览(211)

I know this is duplicate but I could not get reliable solution(for asp.net web).
我只想在会话过期时重定向到登录页面。我已尝试以下操作:

1.使用jquery状态代码

$.ajax({
     type: "POST",
     url: "stream.asmx/SomeMethod",
     contentType: "application/json; charset=utf-8",
     dataType: "json",
     success: function (msg) {
        //success msg
     },
     error: function (request, status, error) {
        if (status = 403) {
            location.href = 'login.aspx';
        }
     }
    });
    • 问题:**对于其他错误也返回相同的状态代码(403),我只希望会话超时。

2.发送会话是否过期的json消息

代码隐藏:

if (!object.Equals(HttpContext.Current.Session["User"], null))
    {
        Id = int.Parse(HttpContext.Current.Session["User"].ToString());
    }
    else
    {
        result = from row in dtscrab.AsEnumerable()
                 select new
                 {
                     redirectUrl = "login.aspx",
                     isRedirect = true
                 };
    }

在$. ajax成功时:

success: function (msg) {
        if (msg.d[0].isRedirect) {
            window.location.href = msg.d[0].redirectUrl;
        }
        else {
            //load containt
        }
     }
    • 问题:**如果会话过期,它不知何故不调用ajax成功行(它确实返回正确的json)。即使这样,如果我在页面中有很多ajax请求(应该全局处理),这也不是一个正确的方法。

然而,我看到这篇文章,这是一个很好的解决方案,但它的mvc使用AuthorizeAttributehandling-session-timeout-in-ajax-calls

So, Is there I can use same concept used in mvc using AuthorizeAttribute in asp.net web api? If not, how I can troubleshoot those issue which I'm facing (any of above two mentioned)?

epfja78i

epfja78i1#

403状态代码将导致jQuery调用failure方法。从第二次尝试开始保留相同的代码,但是将重定向处理程序移到failure方法而不是success方法。在success方法中,像往常一样处理它。

lnxxn5zx

lnxxn5zx2#

问题:

我有同样的问题,在我的剃刀MVC应用程序抛出异常,而ajax调用时,会话超时。
我设法解决这个问题的方法是通过使用一个简单的轻量级操作方法(RAZOR MVC)来监视每个ajax请求,无论请求是否经过身份验证,该方法都会返回一个bool变量。

布局/母版页/脚本文件:

<script>
var AuthenticationUrl = '/Home/GetRequestAuthentication';
var RedirectUrl = '/Account/Logon';

function SetAuthenticationURL(url) {
AuthenticationUrl = url;
}

function RedirectToLoginPage() {
window.location = RedirectUrl; 
}

 $(document).ajaxStart(function () {
 $.ajax({
    url: AuthenticationUrl,
    type: "GET",
    success: function (result) {
        if (result == false) {
            alert("Your Session has expired.Please wait while redirecting you to login page.");
            setTimeout('RedirectToLoginPage()', 1000);
        }
    },
    error: function (data) { debugger; }
});

})
然后在家庭控制器/服务器端,您需要一个方法来验证请求并返回布尔变量。

public ActionResult GetAuthentication ( )
    {
        return Json(Request.IsAuthenticated, JsonRequestBehavior.AllowGet);
    }

这将验证每个ajax请求,如果任何ajax请求的会话过期,它将用一条消息提醒用户,并将用户重定向到登录页面。
我也建议不要使用标准的警报到警报。用户一些工具提示类格式化div警报。标准的JS警报可能会迫使用户在重定向前单击确定。
希望对你有帮助。:)
谢谢,利亚兹

e5nqia27

e5nqia273#

最后,我终于跟了上去。

public class IsAuthorizedAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                var sessions = filterContext.HttpContext.Session;
                if (sessions["User"] != null)
                {
                    return;
                }
                else
                {
                    filterContext.Result = new JsonResult
                    {
                        Data = new
                        {
                            status = "401"
                        },
                        JsonRequestBehavior = JsonRequestBehavior.AllowGet
                    };

                    //xhr status code 401 to redirect
                    filterContext.HttpContext.Response.StatusCode = 401;

                    return;
                }
            }

            var session = filterContext.HttpContext.Session;
            if (session["User"] != null)
                return;

            //Redirect to login page.
            var redirectTarget = new RouteValueDictionary { { "action", "LogOn" }, { "controller", "Account" } };
            filterContext.Result = new RedirectToRouteResult(redirectTarget);
        }
    }

处理客户端

<script type="text/javascript">
    $(document).ajaxComplete(
       function (event, xhr, settings) {
           if (xhr.status == 401) {
               window.location.href = "/Account/LogOn";
           }
    });
</script>
bis0qfac

bis0qfac4#

您可以设置会话超时过期警告,例如....

<script type="text/javascript"> 

//get a hold of the timers
var iddleTimeoutWarning = null;
var iddleTimeout = null;

//this function will automatically be called by ASP.NET AJAX when page is loaded and partial postbacks complete
function pageLoad() { 

    //clear out any old timers from previous postbacks
    if (iddleTimeoutWarning != null)
        clearTimeout(iddleTimeoutWarning);
    if (iddleTimeout != null)
        clearTimeout(iddleTimeout);
    //read time from web.config
    var millisecTimeOutWarning = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeoutWarning"]) * 60 * 1000 %>;
    var millisecTimeOut = <%= int.Parse(System.Configuration.ConfigurationManager.AppSettings["SessionTimeout"]) * 60 * 1000 %>; 

    //set a timeout to display warning if user has been inactive
    iddleTimeoutWarning = setTimeout("DisplayIddleWarning()", millisecTimeOutWarning);
    iddleTimeout = setTimeout("TimeoutPage()", millisecTimeOut);
} 

function DisplayIddleWarning() {
    alert("Your session is about to expire due to inactivity.");
} 

function TimeoutPage() {
    //refresh page for this sample, we could redirect to another page that has code to clear out session variables
    location.reload();
}
5gfr0r5j

5gfr0r5j5#

4xx是HTTP错误状态代码,会导致jquery执行onFailure回调。
另外,当你想要处理有效负载时,要小心使用3xx进行重定向。根据我的经验,InternetExplorer只会在返回3xx状态代码时进行重定向(不看有效负载)。
我会说,抛出一个403并处理这种情况。对客户端来说,403意味着资源访问被禁止。可能有多种原因,我想这是可以的。

rnmwe5a2

rnmwe5a26#

对于那些使用ScriptManager的用户,您可以轻松地检查 AJAX 请求,然后使用以下代码进行重定向:

private void AjaxRedirect(string url)
    {
        Response.StatusCode = 200;
        Response.RedirectLocation = url;
        Response.Write("<html></html>");
        Response.End();
    }

然后检查请求类型并相应地重定向(使用此处的路由):

if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
{
    var redirectUrl = RouteTable.Routes.GetVirtualPath(null, "Default", null).VirtualPath;                            
    AjaxRedirect(redirectUrl);
}
else
{
    Response.RedirectToRoute("Default");
}

“默认”路由是路由集合中定义的路由:

routes.MapPageRouteWithName("Default", "", "~/default.aspx");

如果您愿意,您可以使用以下命令,而不是使用ScriptManager进行 AJAX 请求检查:

if (Request.Headers["X-Requested-With"] == "XMLHttpRequest") { 
   code here...
}

相关问题