我使用$.post()使用Ajax调用servlet,然后使用生成的HTML片段替换用户当前页面中的div元素。但是,如果会话超时,服务器将发送重定向指令,将用户发送到登录页面。在本例中,jQuery用登录页面的内容替换div元素,迫使用户的眼睛看到一个罕见的场景。

如何使用jQuery1.2.6管理Ajax调用的重定向指令?


当前回答

大多数给定的解决方案都使用一种变通方法,使用额外的头或不合适的HTTP代码。这些解决方案很可能会奏效,但感觉有点“粗糙”。我想出了另一个解决方案。

我们使用的WIF被配置为在401响应上重定向(passiveRedirectEnabled=“true”)。重定向在处理正常请求时是有用的,但对AJAX请求不起作用(因为浏览器不会执行302/重定向)。

使用global.asax中的以下代码,可以禁用AJAX请求的重定向:

    void WSFederationAuthenticationModule_AuthorizationFailed(object sender, AuthorizationFailedEventArgs e)
    {
        string requestedWithHeader = HttpContext.Current.Request.Headers["X-Requested-With"];

        if (!string.IsNullOrEmpty(requestedWithHeader) && requestedWithHeader.Equals("XMLHttpRequest", StringComparison.OrdinalIgnoreCase))
        {
            e.RedirectToIdentityProvider = false;
        }
    }

这允许您为AJAX请求返回401个响应,然后javascript可以通过重新加载页面来处理这些响应。重新加载页面将抛出一个401,由WIF处理(WIF将用户重定向到登录页面)。

处理401错误的示例javascript:

$(document).ajaxError(function (event, jqxhr, settings, exception) {

    if (jqxhr.status == 401) { //Forbidden, go to login
        //Use a reload, WIF will redirect to Login
        location.reload(true);
    }
});

其他回答

大多数给定的解决方案都使用一种变通方法,使用额外的头或不合适的HTTP代码。这些解决方案很可能会奏效,但感觉有点“粗糙”。我想出了另一个解决方案。

我们使用的WIF被配置为在401响应上重定向(passiveRedirectEnabled=“true”)。重定向在处理正常请求时是有用的,但对AJAX请求不起作用(因为浏览器不会执行302/重定向)。

使用global.asax中的以下代码,可以禁用AJAX请求的重定向:

    void WSFederationAuthenticationModule_AuthorizationFailed(object sender, AuthorizationFailedEventArgs e)
    {
        string requestedWithHeader = HttpContext.Current.Request.Headers["X-Requested-With"];

        if (!string.IsNullOrEmpty(requestedWithHeader) && requestedWithHeader.Equals("XMLHttpRequest", StringComparison.OrdinalIgnoreCase))
        {
            e.RedirectToIdentityProvider = false;
        }
    }

这允许您为AJAX请求返回401个响应,然后javascript可以通过重新加载页面来处理这些响应。重新加载页面将抛出一个401,由WIF处理(WIF将用户重定向到登录页面)。

处理401错误的示例javascript:

$(document).ajaxError(function (event, jqxhr, settings, exception) {

    if (jqxhr.status == 401) { //Forbidden, go to login
        //Use a reload, WIF will redirect to Login
        location.reload(true);
    }
});

使用statusCode选项,如下所示,重定向通常是301、302状态代码。

$.ajax({
    type: <HTTP_METHOD>,
    url:  {server.url},
    data: {someData: true},
    statusCode: {
        301: function(responseObject, textStatus, errorThrown) {
            //yor code goes here
        },
        302: function(responseObject, textStatus, errorThrown) {
            //yor code goes here
        }           
    }
})
.done(function(data){
    alert(data);
})
.fail(function(jqXHR, textStatus){
    alert('Something went wrong: ' + textStatus);
})
.always(function(jqXHR, textStatus) {
   alert('Ajax request was finished')
});

把弗拉基米尔·普拉德尼科夫和托马斯·汉森所说的话放在一起:

更改服务器端代码以检测它是否是XHR。如果是,则将重定向的响应代码设置为278。在django:

如果request.is_ajax():响应状态代码=278

这使得浏览器将响应视为成功,并将其交给您的Javascript。

在JS中,确保通过Ajax提交表单,检查响应代码并根据需要重定向:

$(“#my form”).submit(函数(事件){event.prpreventDefault();var选项={url:$(this).attr('action'),类型:'POST',complete:函数(响应,textStatus){如果(response.status==278){window.location=响应.getResponseHeader(“位置”)}否则{…您的代码在这里…}},data:$(this).serialize(),}; $.ajax(选项);});

使用低级$.ajax()调用:

$.ajax({
  url: "/yourservlet",
  data: { },
  complete: function(xmlHttp) {
    // xmlHttp is a XMLHttpRquest object
    alert(xmlHttp.status);
  }
});

尝试此操作进行重定向:

if (xmlHttp.code != 200) {
  top.location.href = '/some/other/page';
}

作为ajax的替代,正在开发一个新的Fetch API,它允许手动重定向处理。您需要检查当前的浏览器支持是否足以满足您的需要。