Advertisement
Advertisement


How to manage a redirect request after a jQuery Ajax call


Question

I'm using $.post() to call a servlet using Ajax and then using the resulting HTML fragment to replace a div element in the user's current page. However, if the session times out, the server sends a redirect directive to send the user to the login page. In this case, jQuery is replacing the div element with the contents of the login page, forcing the user's eyes to witness a rare scene indeed.

How can I manage a redirect directive from an Ajax call with jQuery 1.2.6?

2016/01/22
1
1391
1/22/2016 8:21:45 PM

Accepted Answer

The solution that was eventually implemented was to use a wrapper for the callback function of the Ajax call and in this wrapper check for the existence of a specific element on the returned HTML chunk. If the element was found then the wrapper executed a redirection. If not, the wrapper forwarded the call to the actual callback function.

For example, our wrapper function was something like:

function cbWrapper(data, funct){
    if($("#myForm", data).length > 0)
        top.location.href="login.htm";//redirection
    else
        funct(data);
}

Then, when making the Ajax call we used something like:

$.post("myAjaxHandler", 
       {
        param1: foo,
        param2: bar
       },
       function(data){
           cbWrapper(data, myActualCB);
       }, 
       "html"
);

This worked for us because all Ajax calls always returned HTML inside a DIV element that we use to replace a piece of the page. Also, we only needed to redirect to the login page.

2016/08/31
100
8/31/2016 6:15:36 AM


I solved this issue by:

  1. Adding a custom header to the response:

    public ActionResult Index(){
        if (!HttpContext.User.Identity.IsAuthenticated)
        {
            HttpContext.Response.AddHeader("REQUIRES_AUTH","1");
        }
        return View();
    }
    
  2. Binding a JavaScript function to the ajaxSuccess event and checking to see if the header exists:

    $(document).ajaxSuccess(function(event, request, settings) {
        if (request.getResponseHeader('REQUIRES_AUTH') === '1') {
           window.location = '/';
        }
    });
    
2017/11/08

No browsers handle 301 and 302 responses correctly. And in fact the standard even says they should handle them "transparently" which is a MASSIVE headache for Ajax Library vendors. In Ra-Ajax we were forced into using HTTP response status code 278 (just some "unused" success code) to handle transparently redirects from the server...

This really annoys me, and if someone here have some "pull" in W3C I would appreciate that you could let W3C know that we really need to handle 301 and 302 codes ourselves...! ;)

2015/08/19

I like Timmerz's method with a slight twist of lemon. If you ever get returned contentType of text/html when you're expecting JSON, you are most likely being redirected. In my case, I just simply reload the page, and it gets redirected to the login page. Oh, and check that the jqXHR status is 200, which seems silly, because you are in the error function, right? Otherwise, legitimate error cases will force an iterative reload (oops)

$.ajax(
   error:  function (jqXHR, timeout, message) {
    var contentType = jqXHR.getResponseHeader("Content-Type");
    if (jqXHR.status === 200 && contentType.toLowerCase().indexOf("text/html") >= 0) {
        // assume that our login has expired - reload our current page
        window.location.reload();
    }

});
2011/09/14

Use the low-level $.ajax() call:

$.ajax({
  url: "/yourservlet",
  data: { },
  complete: function(xmlHttp) {
    // xmlHttp is a XMLHttpRquest object
    alert(xmlHttp.status);
  }
});

Try this for a redirect:

if (xmlHttp.code != 200) {
  top.location.href = '/some/other/page';
}
2008/10/17

I just wanted to share my approach as this might it might help someone:

I basically included a JavaScript module which handles the authentication stuff like displaying the username and also this case handling the redirect to the login page.

My scenario: We basically have an ISA server in between which listens to all requests and responds with a 302 and a location header to our login page.

In my JavaScript module my initial approach was something like

$(document).ajaxComplete(function(e, xhr, settings){
    if(xhr.status === 302){
        //check for location header and redirect...
    }
});

The problem (as many here already mentioned) is that the browser handles the redirect by itself wherefore my ajaxComplete callback got never called, but instead I got the response of the already redirected Login page which obviously was a status 200. The problem: how do you detect whether the successful 200 response is your actual login page or just some other arbitrary page??

The solution

Since I was not able to capture 302 redirect responses, I added a LoginPage header on my login page which contained the url of the login page itself. In the module I now listen for the header and do a redirect:

if(xhr.status === 200){
    var loginPageRedirectHeader = xhr.getResponseHeader("LoginPage");
    if(loginPageRedirectHeader && loginPageRedirectHeader !== ""){
        window.location.replace(loginPageRedirectHeader);
    }
}

...and that works like charm :). You might wonder why I include the url in the LoginPage header...well basically because I found no way of determining the url of GET resulting from the automatic location redirect from the xhr object...

2012/05/23

Source: https://stackoverflow.com/questions/199099
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]