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

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


当前回答

使用ASP.NET MVC RedirectToAction方法可能会出现此问题。为了防止表单在div中显示响应,您可以简单地使用$.ajaxSetup对响应进行某种ajax响应过滤。如果响应包含MVC重定向,则可以在JS端评估此表达式。JS的示例代码如下:

$.ajaxSetup({
    dataFilter: function (data, type) {
        if (data && typeof data == "string") {
            if (data.indexOf('window.location') > -1) {
                eval(data);
            }
        }
        return data;
    }
});

如果数据为:“window.location='/Acount/Login'”,则过滤器将捕捉到该数据并进行评估以进行重定向,而不是让数据显示。

其他回答

我在一个我正在修补的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在我完成我的回答后,立即通过了我的服务取消请求!

使用低级$.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';
}

我认为更好的处理方法是利用现有的HTTP协议响应代码,特别是401未授权。

我是这样解决的:

服务器端:如果会话过期,请求为ajax。发送401响应代码头客户端:绑定到ajax事件$('body').bind('ajaxSuccess',函数(事件,请求,设置){if(401==请求状态){window.location='/users/login';}}).bind('ajaxError',函数(事件、请求、设置){if(401==请求状态){window.location='/users/login';}});

IMO这是更通用的,您没有编写一些新的自定义规范/标题。您也不必修改任何现有的ajax调用。

编辑:根据@Rob下面的评论,401(验证错误的HTTP状态代码)应该是指示符。有关详细信息,请参阅403禁止与401未授权HTTP响应。尽管如此,一些web框架使用403来处理身份验证和授权错误,因此进行相应的调整。谢谢Rob。

此外,您可能希望将用户重定向到给定的标头URL。因此,最终将如下所示:

$.ajax({
    //.... other definition
    complete:function(xmlHttp){
        if(xmlHttp.status.toString()[0]=='3'){
        top.location.href = xmlHttp.getResponseHeader('Location');
    }
});

UPD:机会。有相同的任务,但不起作用。做这些事。当我找到解决方案时,我会给你看。

我发现的另一个解决方案(如果要设置全局行为,尤其有用)是将$.ajaxsetup()方法与statusCode属性一起使用。正如其他人指出的,不要使用重定向状态码(3xx),而是使用4xx状态码并处理客户端重定向。

$.ajaxSetup({ 
  statusCode : {
    400 : function () {
      window.location = "/";
    }
  }
});

将400替换为要处理的状态代码。正如前面提到的401未经授权可能是个好主意。我使用400,因为它非常不具体,我可以在更具体的情况下使用401(比如错误的登录凭据)。因此,当会话超时并且您处理重定向客户端时,后端应该返回4xx错误代码,而不是直接重定向。即使使用backbone.js这样的框架,也非常适合我