How to re-play an AJAX request in jQuery after an authentication error
I’m building a mobile web app that is basically one HTML file + backbone.js + other JavaScript magic. The app is authenticated, so the user needs to be able to login. Thankfully the server returns a 403 if a request is not authorised to access the requested endpoint. Ideally, if that happened, a login form would pop up, the user would enter their details, and the system would continue on it’s merry way.
With jQuery, this is surprisingly easy.
You can setup global settings using the jQuery.ajaxSetup method. These settings get injected into every AJAX request you make via the jQuery API. The attribute we are interested in setting is the statusCode attribute: in particular the 403 function.
jQuery.ajaxSetup(
statusCode: {
403: function() {
// This calls a backbone view that renders a login window, then
// calls the success function one the user has been authenticated
// The call back simply re-runs $.ajax using the current context object,
// which conveniently is a hash of the original AJAX request params.
var sessionLogin = new SessionsLoginView();
var context = this;
sessionLogin.render({
success: function() {
$.ajax(context);
}
});
}
}
});
What happens is a 403 response code gets captured, we save the current AJAX object into the context variable, we then call the login form, which gets the user to authenticate and then calls the success function. It just so happens that the context variable stores a hash of the original AJAX request settings, which we pass directly into $.ajax. This in effect replays the query, now with the new authentication token!
The beauty of this (besides the fact that it’s hands off, and nicely abstracted) is that it will handle changing passwords on the server gracefully (it’ll just pop up the login form again), as well as handle incorrect usernames or passwords.