I recently came across a problem in an application i’m working on where we had a modal dialog being opened, with the contents coming from a jQuery ajax request. In general this was working fine, however while testing I came across an issue where, randomly, the dialog did not show up. Further investigation revealed this to be due to the session expiring, and therefore the user losing authentication.
When using jQuery ajax, that results in a 302, the browser tends to act on the 302 before jQuery gets a chance to examine the HTTP status.This has been solved before in many different ways. However none of them seemed generic enough, and each had issues, for example, any 302 resulted in the user being redirected to the sign in page if the 302 is the result of an ajax call.
Our final solution to the problem involved creating our own HTTP status (308, which is currently unused), and sending that back. So, on to the code.
Firstly in your global.asax file, we need to intercept ajax sourced 302’s. Once we have identified those requests, clear the response, and set our status code to our pretend code of 308.
protected void Application_EndRequest()
{
var context = new HttpContextWrapper(Context);
if (Context.Response.StatusCode == 302 && context.Request.IsAjaxRequest())
{
Context.Response.Clear();
Context.Response.StatusCode = 308;
}
}
Now to deal with this nicely in your jQuery calls, make sure you have a generic scripts.js file on every page to collate all your general scripts, and add the below.
$(document).ajaxError(function (e, request, errorThrown, exception) {
if (request.status == "308") {
window.location = request.getResponseHeader('location');
}
});
Here, we bind the ajaxError function to our own custom function so that we can deal with these little 308 responses. This function will get called every time jQuery encounters an error in the ajax call (jQuery treats everything other than an Http200/ok as an error). We check for our 308 status, and if that’s the case, redirect the user to the location as set by the redirect.
So this works perfectly for every case we have encountered so far, MVC controller redirects, authentication fails etc.
Hoping this helps somebody.