Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$http get to a Rails ApplicationController gives "HTTP Error 406 Not acceptable" against angular 1.1+ build [closed]

If you are calling a Rails service like this:

 $http.get(url).success(successFn)
               .error(
                      function(data, status, headers, config) {
                               console.log('Failed');
                      }
                     );

And your Rails ApplicationController responds like this:

   def your_service

      # do some stuff

      respond_to do |format|
         format.js { render 'shared/common_js' }
      end
   end

Using angular 1.0.x everything goes on smoothly and your service answers OK 200.

Then I tried the same code against the unstable 1.1.x build and things stopped working with a HTTP Error 406 Not acceptable.

like image 684
rubyno Avatar asked Jan 08 '13 07:01

rubyno


1 Answers

I spent a few hours investigating this, hopefully this will save someone else's time.

After a debug session, finally I spotted that the difference was in the request headers:

1.0.3 (at this time):  {X-Requested-With: "XMLHttpRequest", Accept: "application/json, text/plain, */*", X-XSRF-TOKEN: undefined} 

1.1.1 (at this time):  {Accept: "application/json, text/plain, */*", X-XSRF-TOKEN: undefined} 

So I googled for "X-Requested-With: XMLHttpRequest removed" and I finally spotted out this commit:

($http): remove 'X-Requested-With' from header defaults https://github.com/angular/angular.js/commit/3a75b1124d062f64093a90b26630938558909e8d

(This removal was the result of some discussions, and is basically meant to allow smoother CORS requests)

With this removal, Rails can no more find is way through the service, that is:

format.js { render 'shared/common_js' }  

gets no more triggered (actually format.html is)!

A possible fix is:

    $http( {method: 'GET', url: url , headers: {'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json, text/plain, */*'}})
           .success(successFn)
           .error(
                           function(data, status, headers, config) {
                               console.log('Fail');
                             }
                         );

Otherwise, as stated in the commit, you can bring back the missing headers like this:

myAppModule.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
}]);

Hope this helpful, cheers.

like image 117
rubyno Avatar answered Oct 05 '22 23:10

rubyno