Slee
Slee

Reputation: 28248

jQuery AJAX see redirect as status 200 not 302?

I am using jQuery and the jQuery.form plugin to submit my form (also using ASP.Net MVC).

Problem is the user is in a section of the site that uses forms authentication and if their auth cookie expires during their time on the page instead of getting back a status of 302, which would be the redirect to the login page, I still get 200?

In FireBug I see the 302 Found and then my login page is served next as a 200 which is the status code sent back to my Ajax call. How do I detect that they have been logged out if I never see the 302 sent back to the jQuery form plugin?

Upvotes: 10

Views: 8493

Answers (5)

user342706
user342706

Reputation:

I really like this solution. By changing the 302 response on ajax requests to a 401 it allows you to setup your ajax on the client side to monitor any ajax request looking for a 401 and if it finds one to redirect to the login page. Very simple and effective.

Global.asax:

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 302 &&
        Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    {
        Context.Response.Clear();
        Context.Response.StatusCode = 401;
    }
}

Client Side Code:

 $(function () {
      $.ajaxSetup({
        statusCode: {
          401: function () {
            location.href = '/Logon.aspx?ReturnUrl=' + location.pathname;
          }
        }
      });
    });

Upvotes: 9

sillyMunky
sillyMunky

Reputation: 1278

I'm pretty sure you will never get the 302 in the completed status of the XHR object. If a redirect occurs then the connection is still in process until you see the response from the login page (which should be 200, if it exists).

However, why do you need to see the 302? Surely if you are getting a redirect to login.php then simply getting the url (or parsing for content) of the returned response tells you they have been logged out?

An alternative, only if you want to know as soon as the session has expired (before they do some action), is to poll the server using setTimeout or similar to get information on the authentication status.

Good luck.

Upvotes: 0

jarcoal
jarcoal

Reputation: 1455

This is the solution I've used in the past:

Server side:

When I'm checking to see if a session is still valid, I also keep an eye out for the "X-Requested-With" header, which should be "XMLHttpRequest" if you're using jQuery (NOTE: IE tends to return the header name in lower case, so watch for that as well). If the session has indeed expired and the header is present, instead of using an HTTP redirect, I respond with a simple JSON object like this:

{ "SESSION": "EXPIRED" }

Client side:

In my onload code, I use jQuery's ajaxComplete event to check all incoming request payloads for the session expired object. The code looks something like this:

$(window).ajaxComplete(function(ev, xmlhr, options){
    try {
        var json = $.parseJSON(xmlhr.responseText);
    }
    catch(e) {
        console.log('Session OK');
        return;
    }

    if ($.isPlainObject(json) && json.SESSION == 'EXPIRED') {
        console.log('Session Expired');

        //inform the user and window.location them somewhere else

        return;
    }

    console.log('Session OK');
});

Upvotes: 0

andres descalzo
andres descalzo

Reputation: 14967

try with cache: false cache option in jquery ajax:

$.ajax({
  url: "test.html",
  cache: false,
  success: function(html){
    $("#results").append(html);
  }
});

---EDIT Try with this in C# code :

protected void Page_Load(object sender, System.EventArgs e)
{
   Response.Cache.SetCacheability(HttpCacheability.NoCache);
   ...
}

Upvotes: 1

Jason Berry
Jason Berry

Reputation: 2469

A similar problem has been encountered before. Is the solution given in this question helpful?

Upvotes: 0

Related Questions