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

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


当前回答

我认为更好的处理方法是利用现有的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。

其他回答

我只想锁定整个页面的任何ajax请求@SuperG让我开始了。以下是我的结论:

// redirect ajax requests that are redirected, not found (404), or forbidden (403.)
$('body').bind('ajaxComplete', function(event,request,settings){
        switch(request.status) {
            case 301: case 404: case 403:                    
                window.location.replace("http://mysite.tld/login");
                break;
        }
});

我想特别检查某些http状态代码以作为我的决定的基础。然而,您可以绑定到ajaxError以获得除成功之外的任何结果(可能只有200?)

$('body').bind('ajaxError', function(event,request,settings){
    window.location.replace("http://mysite.tld/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在我完成我的回答后,立即通过了我的服务取消请求!

您还可以钩住XMLHttpRequest发送原型。这将使用一个处理程序处理所有发送(jQuery/dojo/etc)。

我编写这段代码是为了处理一个500页的过期错误,但它应该可以捕获200个重定向。准备好有关readyState含义的XMLHttpRequest onreadystatechange上的维基百科条目。

// Hook XMLHttpRequest
var oldXMLHttpRequestSend = XMLHttpRequest.prototype.send;

XMLHttpRequest.prototype.send = function() {
  //console.dir( this );

  this.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 500 && this.responseText.indexOf("Expired") != -1) {
      try {
        document.documentElement.innerHTML = this.responseText;
      } catch(error) {
        // IE makes document.documentElement read only
        document.body.innerHTML = this.responseText;
      }
    }
  };

  oldXMLHttpRequestSend.apply(this, arguments);
}

让我再次引用@Steg描述的问题

我有一个和你类似的问题。我执行一个ajax请求可能的响应:将浏览器重定向到新页面将当前页面上的现有HTML表单替换为新的一

IMHO这是一个真正的挑战,必须正式扩展到当前的HTTP标准。

我相信新的Http标准将使用新的状态代码。意思:目前301/302告诉浏览器去把这个请求的内容取到一个新的位置。

在扩展标准中,它会说如果响应状态为:308(只是一个示例),那么浏览器应该将主页重定向到提供的位置。

话虽如此;我倾向于模仿这种未来的行为,因此当需要document.redirect时,我让服务器响应如下:

status: 204 No Content
x-status: 308 Document Redirect
x-location: /login.html

当JS获得“status:204”时,它检查x-status:308标头的存在,并将document.redirect指向位置标头中提供的页面。

这对你有意义吗?

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

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

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

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

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