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

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


当前回答

我这样解决了这个问题:

添加一个中间件来处理响应,如果是对ajax请求的重定向,则使用重定向url将响应更改为正常响应。

class AjaxRedirect(object):
  def process_response(self, request, response):
    if request.is_ajax():
      if type(response) == HttpResponseRedirect:
        r = HttpResponse(json.dumps({'redirect': response['Location']}))
        return r
    return response

然后在ajaxComplete中,如果响应包含重定向,则它必须是重定向,因此请更改浏览器的位置。

$('body').ajaxComplete(function (e, xhr, settings) {
   if (xhr.status == 200) {
       var redirect = null;
       try {
           redirect = $.parseJSON(xhr.responseText).redirect;
           if (redirect) {
               window.location.href = redirect.replace(/\?.*$/, "?next=" + window.location.pathname);
           }
       } catch (e) {
           return;
       }
   }
}

其他回答

我通过在login.php页面中放置以下内容来解决这个问题。

<script type="text/javascript">
    if (top.location.href.indexOf('login.php') == -1) {
        top.location.href = '/login.php';
    }
</script>

这对我有用:

success: function(data, textStatus, xhr) {

        console.log(xhr.status);
}

一旦成功,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';
}

我阅读了这个问题,并实现了所述的将响应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。我发现这种方法要好得多。

您还可以钩住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);
}