19.11.12

jQuery and HTTP acceptable content-type request header

As a consequence of the fact that SAW turns into the single-page application, the user authentication process required an adoption to use XHR requests. In fact the default mode of operation for devise is, whenever user is not authenticated, to use HTTP 302 status to forward web browser to the authentication page. For a RESTful client application this is not a desired behavior as it confuses backbone in where the particular resource can be found. In fact the proper behavior is to return HTTP 401 status, so that it can be caught and client can decide how to proceed.

Trying to implement this I found that my back-end (devise & RoR) is supporting multiple content-types for the request, and it would be most happy to deliver HTML (over JSON). To my surprise specifying JSON as desired content-type in jQuery still resulted in getting 302. Careful investigation resulted in finding that no matter what is the desired content-type, jQuery always attaches */*  to the list of accepted types (through allTypes variable). I can imagine that */* should serve as a fall-back for the situation when the desired content-type is not available, but in that case */* should have a different weight (q parameter). Specifying them in the single header line makes the server treat desired content-type and fall-back as equal.

In fact removing "allTypes" has fixed the problem. I'm now getting 401 which can be caught globally, save the requested URL in localStorage, and perform the right redirection:


jQuery(function() {
   jQuery("body").ajaxError(function(event, request, settings){
    if( request.status === 401 ) {
        localStorage.setItem('SAWurl',window.location.href);
        alert( "You are not logged in!" );
        window.location.href="/users/sign_in";
        }
   });
});


I would be eager to hear your opinion whenever this is a bug or a feature of jQuery.

No comments:

Post a Comment