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

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


当前回答

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

其他回答

使用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')
});

我阅读了这个问题,并实现了所述的将响应HTTP状态代码设置为278的方法,以避免浏览器透明地处理重定向。尽管这起了作用,但我还是有点不满意,因为这有点黑客。

在深入研究之后,我放弃了这种方法,改用JSON。在这种情况下,对AJAX请求的所有响应都具有状态代码200,并且响应的主体包含在服务器上构造的JSON对象。然后,客户端上的JavaScript可以使用JSON对象来决定需要做什么。

我有一个和你类似的问题。我执行一个AJAX请求,它有两种可能的响应:一种是将浏览器重定向到新页面,另一种是用新页面替换当前页面上的现有HTML表单。执行此操作的jQuery代码类似于:

$.ajax({
    type: "POST",
    url: reqUrl,
    data: reqBody,
    dataType: "json",
    success: function(data, textStatus) {
        if (data.redirect) {
            // data.redirect contains the string URL to redirect to
            window.location.href = data.redirect;
        } else {
            // data.form contains the HTML for the replacement form
            $("#myform").replaceWith(data.form);
        }
    }
});

JSON对象“data”在服务器上构造为有两个成员:data.redirect和data.form。我发现这种方法要好得多。

这对我有用:

success: function(data, textStatus, xhr) {

        console.log(xhr.status);
}

一旦成功,ajax将获得浏览器从服务器获得的相同状态代码并执行它。

最后,我通过添加自定义HTTP头来解决这个问题。就在服务器端响应每个请求之前,我将当前请求的url添加到响应的头部。

我在服务器上的应用程序类型是Asp.NetMVC,这是一个很好的地方。在Global.asax中,我实现了application_EndRequest事件,因此:

    public class MvcApplication : System.Web.HttpApplication
    {

    //  ...
    //  ...

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            var app = (HttpApplication)sender;
            app.Context.Response.Headers.Add("CurrentUrl",app.Context. Request.CurrentExecutionFilePath);
        }

    }

它非常适合我!现在,在JQuery$.post的每个响应中,我都有请求的url和其他响应头,这些响应头是post方法的结果,状态为302、303。

另一个重要的是,不需要在服务器端或客户端修改代码。

下一个是能够访问动作后的其他信息,例如错误、消息和。。。,以这种方式。

我发布了这个,也许可以帮助某人:)

我知道这个话题已经过时了,但我将给出另一种我已经发现并在这里描述过的方法。基本上,我使用的是ASP.MVC和WIF(但这对于本主题的上下文来说并不重要——无论使用哪种框架,答案都是足够的。线索保持不变——在执行ajax请求时处理与身份验证失败相关的问题)。

下面显示的方法可以应用于所有开箱即用的ajax请求(如果它们显然没有重新定义beforeEnd事件)。

$.ajaxSetup({
    beforeSend: checkPulse,
    error: function (XMLHttpRequest, textStatus, errorThrown) {
        document.open();
        document.write(XMLHttpRequest.responseText);
        document.close();
    }
});

在执行任何ajax请求之前,调用CheckPulse方法(可以是任何最简单的控制器方法):

[Authorize]
public virtual void CheckPulse() {}

如果用户未经身份验证(令牌已过期),则无法访问该方法(受Authorize属性保护)。因为框架在令牌过期时处理身份验证,所以它将http状态302置于响应中。如果您不希望浏览器透明地处理302响应,请在Global.asax中捕获它,并将响应状态更改为200 OK。此外,添加header,它指示您以特殊方式处理此类响应(稍后在客户端):

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 302
        && (new HttpContextWrapper(Context)).Request.IsAjaxRequest())
    {                
        Context.Response.StatusCode = 200;
        Context.Response.AddHeader("REQUIRES_AUTH", "1");
    }
}

最后在客户端检查这样的自定义头。如果存在,则应该完成到登录页面的完全重定向(在我的情况下,window.location被来自请求的url替换,该url由我的框架自动处理)。

function checkPulse(XMLHttpRequest) {
    var location = window.location.href;
    $.ajax({
        url: "/Controller/CheckPulse",
        type: 'GET',
        async: false,
        beforeSend: null,
        success:
            function (result, textStatus, xhr) {
                if (xhr.getResponseHeader('REQUIRES_AUTH') === '1') {
                    XMLHttpRequest.abort(); // terminate further ajax execution
                    window.location = location;
                }
            }
    });
}