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

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


当前回答

有些人可能会发现以下内容很有用:

我希望客户机被重定向到登录页面,以执行在没有授权令牌的情况下发送的任何rest操作。由于我的所有其余操作都是基于Ajax的,所以我需要一种很好的通用方法来重定向到登录页面,而不是处理Ajax成功函数。

这是我所做的:

在任何Ajax请求中,我的服务器都会返回Json 200响应“需要认证”(如果客户端需要认证)。

Java(服务器端)中的简单示例:

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    private final Logger m_logger = LoggerFactory.getLogger(AuthenticationFilter.class);

    public static final String COOKIE_NAME = "token_cookie"; 

    @Override
    public void filter(ContainerRequestContext context) throws IOException {        
        // Check if it has a cookie.
        try {
            Map<String, Cookie> cookies = context.getCookies();

            if (!cookies.containsKey(COOKIE_NAME)) {
                m_logger.debug("No cookie set - redirect to login page");
                throw new AuthenticationException();
            }
        }
        catch (AuthenticationException e) {
            context.abortWith(Response.ok("\"NEED TO AUTHENTICATE\"").type("json/application").build());
        }
    }
}

在我的Javascript中,我添加了以下代码:

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    var originalSuccess = options.success;

    options.success = function(data) {
        if (data == "NEED TO AUTHENTICATE") {
            window.location.replace("/login.html");
        }
        else {
            originalSuccess(data);
        }
    };      
});

就这样。

其他回答

最后,我通过添加自定义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。

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

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

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

没有浏览器正确处理301和302响应。事实上,标准甚至说他们应该“透明”地处理它们,这对于Ajax库供应商来说是一个非常头疼的问题。在RaAjax中,我们被迫使用HTTP响应状态代码278(只是一些“未使用”的成功代码)来透明地处理来自服务器的重定向。。。

这真的让我很恼火,如果这里有人对W3C有一些“吸引力”,我会很感激你能让W3C知道我们确实需要自己处理301和302代码…!;)

我在一个我正在修补的django应用程序上遇到了这个问题(免责声明:我正在修补以学习,绝不是专家)。我想做的是使用jQueryajax向资源发送DELETE请求,在服务器端删除它,然后(基本上)将重定向返回主页。当我从python脚本发送HttpResponseRedirect('/theRedirect/')时,jQuery的ajax方法收到的是200而不是302。因此,我所做的是发送一个300的回复,其中包括:

response = HttpResponse(status='300')
response['Location'] = '/the-redirect/' 
return  response

然后,我使用jQuery.ajax在客户端上发送/处理请求,如下所示:

<button onclick="*the-jquery*">Delete</button>

where *the-jquery* =
$.ajax({ 
  type: 'DELETE', 
  url: '/resource-url/', 
  complete: function(jqxhr){ 
    window.location = jqxhr.getResponseHeader('Location'); 
  } 
});

也许使用300并不“正确”,但至少它的工作方式和我想的一样。

PS:这是一个巨大的痛苦,在移动版SO上编辑。愚蠢的ISP在我完成我的回答后,立即通过了我的服务取消请求!

在servlet中,您应该将response.setStatus(response.SC_MOVED_PERMANENTLY);要发送重定向所需的“301”xmlHttp状态。。。

在$.ajax函数中,不应使用.toString()函数。。。,只是

如果(xmlHttp.status==301){top.location.href='xxxx.jsp';}

问题是它不是很灵活,你无法决定要重定向到哪里。。

通过servlet重定向应该是最好的方法。但我仍然找不到正确的方法。

我通过以下方式解决了这个问题:

向响应中添加自定义标头:公共操作结果索引(){if(!HttpContext.User.Identity.IsAuthenticated){HttpContext.Response.AddHeader(“REQUIRES_AUTH”,“1”);}return View();}将JavaScript函数绑定到ajaxSuccess事件并检查标头是否存在:$(document).ajaxSuccess(函数(事件、请求、设置){if(request.getResponseHeader('REQUIRES_AUTH')==“1”){window.location='/';}});