Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force HTTP interceptor in dynamic ngSrc request

Tags:

angularjs

I've created an AngularJS application that loads images from an OAuth secured backend. My OAuth library is configured by adding an extra interceptor to the Angular $httpProvider to add the correct authentication header.

My source code in my HTML template looks like this:

<img ng-src="{{ '/users/1/images/' + imageId }}">

My problem is that the http request that is created by the ngSrc directive is ignored by the $http implementation, which results in a request with the wrong authentication. The normal API calls function correct (the ones invoked by my controllers/services by using $http and $resource directly).

like image 226
Mats Stijlaart Avatar asked Jan 08 '14 13:01

Mats Stijlaart


3 Answers

Based on Michal's answer the directive could look like the below

app.directive('httpSrc', [
        '$http', function ($http) {
            var directive = {
                link: link,
                restrict: 'A'
            };
            return directive;

            function link(scope, element, attrs) {
                var requestConfig = {
                    method: 'Get',
                    url: attrs.httpSrc,
                    responseType: 'arraybuffer',
                    cache: 'true'
                };

                $http(requestConfig)
                    .then(function(response) {
                        var arr = new Uint8Array(response.data);

                        var raw = '';
                        var i, j, subArray, chunk = 5000;
                        for (i = 0, j = arr.length; i < j; i += chunk) {
                            subArray = arr.subarray(i, i + chunk);
                            raw += String.fromCharCode.apply(null, subArray);
                        }

                        var b64 = btoa(raw);

                        attrs.$set('src', "data:image/jpeg;base64," + b64);
                    });
            }

        }
    ]);

You would then use it as follows

<img http-src="www.test.com/something.jpeg">
like image 143
Bradley MIller Avatar answered Oct 09 '22 02:10

Bradley MIller


The ngSrc directive just controls the usual src attribute for an img, which makes the browser request the image just like any other image, not via Javascript, so I don't think this can be intercepted.

However, what you could do, is write a new directive, save httpSrc. This then can fetch the image using a call to $http, and then create a data URI with the response using something like Using raw image data from ajax request for data URI (although I'm not sure of the browser support for it).

like image 28
Michal Charemza Avatar answered Oct 09 '22 02:10

Michal Charemza


As said here you can use angular-img-http-src (bower install --save angular-img-http-src if you use Bower).

If you look at the code, it uses URL.createObjectURL and URL.revokeObjectURL which are still draft on 19 April 2016. So look if your browser supports it.

In order to use it, declare 'angular.img' as a dependency to your app module (angular.module('myapp', [..., 'angular.img'])), and then in your HTML you can use http-src attribute for <img> tag.

In your example, you can write: <img http-src="/users/1/images/{{imageId}}">

like image 36
Anthony O. Avatar answered Oct 09 '22 01:10

Anthony O.