AngularJS - How to deflate and encode/decode to base64 all jsons request?

Jakub Kuchar picture Jakub Kuchar · Dec 30, 2012 · Viewed 54.6k times · Source

Lets say i have several $resources and some $http around my angular application:

myApp.factory('Note', function($resource) {

  return $resource('http://', {id: '@id'}, 
    { 'index': { method: 'GET', isArray: true },
      'update': { method: 'PUT'},
    });
  });

with controller

myApp.controller('NotesController',function NotesController($scope, Note, AuthenticationService) {

$scope.notes = Note.index({}, function(data){
    console.log('success, got data: ', data);
    $scope.response = "yoy!"
  }, function(err){
    console.log('error, got data: ', err);
    $scope.response = "yay!"
  }); 
});

and some request are made by $http directly like authentication

var request = $http.post('http://', {email: email, password: password});

Where and How i can tell angular to deflate and encode/decode JSONs to base64 before the actual request is made / response is receive?

I quess i will wrap external libraries for deflate and encode/decode into factory. And then this factory will be injected somehere? Like $httpBackend ?

Answer

pkozlowski.opensource picture pkozlowski.opensource · Dec 30, 2012

You should have a look at the request / response transformers for the $http service: http://docs.angularjs.org/api/ng.$http

Request / response transformers are simply functions that can be invoked before content is sent / handed back to the caller. You can specify transforming functions globally (for all requests / responses) as well as per-request basis:

To override these transformation locally, specify transform functions as transformRequest and/or transformResponse properties of the config object. To globally override the default transforms, override the $httpProvider.defaults.transformRequest and $httpProvider.defaults.transformResponse properties of the $httpProvider.

To define global request / response transformers one would write the code along those lines (it is more like pseudo-code, won't work in all browsers, see notes about Base64 below):

angular.module('sample', [], function($httpProvider) {

    $httpProvider.defaults.transformRequest = function(data, headersGetter) {
        return btoa(JSON.stringify(data));
    };

    $httpProvider.defaults.transformResponse = function(data, headersGetter) {
        return JSON.parse(atob(data));
    };

})

Of course your transforming code could be more sophisticated and depend on request / response headers but the general idea is here. The jsFiddle with the code (check the console to see that a request gets transformed, you need to use Mozilla or a WebKit browser): http://jsfiddle.net/Ydt5j/

For the actual conversion from / to Base64 check this question: How can you encode a string to Base64 in JavaScript?