Принудительный перехватчик HTTP в динамическом запросе ngSrc

Я создал приложение AngularJS, которое загружает изображения из защищенного бэкэнда OAuth. Моя библиотека OAuth настраивается путем добавления дополнительного перехватчика в Angular $httpProvider добавить правильный заголовок аутентификации.

Мой исходный код в моем HTML Шаблон выглядит так:

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

Моя проблема заключается в том, что запрос http, который создается ngSrc директива игнорируется $http реализация, которая приводит к запросу с неверной аутентификацией. Обычные функции API-вызовов корректны (те, которые были вызваны моими контроллерами / сервисами с помощью $http а также $resource напрямую).

4 ответа

Решение

ngSrc директива просто контролирует обычное src атрибут для img, который заставляет браузер запрашивать изображение, как и любое другое изображение, не через Javascript, поэтому я не думаю, что это может быть перехвачено.

Однако, что вы могли бы сделать, это написать новую директиву, сохраните httpSrc. Затем можно получить изображение с помощью вызова $httpи затем создайте URI данных с ответом, используя что-то вроде использования необработанных данных изображения из запроса ajax для URI данных (хотя я не уверен в его поддержке браузером).

На основании ответа Михала директива может выглядеть так:

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);
                    });
            }

        }
    ]);

Вы бы тогда использовали его следующим образом

<img http-src="www.test.com/something.jpeg">

Как сказано здесь, вы можете использовать angular-img-http-src (bower install --save angular-img-http-src если вы используете Bower).

Если вы посмотрите на код, он использует URL.createObjectURL а также URL.revokeObjectURL которые все еще находятся в стадии разработки 19 апреля 2016 года. Посмотрите, поддерживает ли ваш браузер это.

Чтобы использовать его, объявите 'angular.img' как зависимость от вашего модуля приложения (angular.module('myapp', [..., 'angular.img'])), а затем в вашем HTML вы можете использовать http-src атрибут для <img> тег.

В вашем примере вы можете написать: <img http-src="/users/1/images/{{imageId}}">

Это немного старый, но я подумал, что я бы добавил еще один метод для поиска изображения без перехватчика. В моем случае мне нужно было найти путь к изображению из конвейера ресурсов rails.

Был блог от Codetunes ( http://codetunes.com/2014/5-tips-on-how-to-use-angularjs-with-rails-that-changed-how-we-work/), в котором описывалось, как они найти шаблоны. Это использует перехватчик, но не работает для изображений.

Решение, которое я использовал, требует, чтобы вы использовали модель для значения ng-src. В рамках этой модели я вызываю вспомогательный метод из службы, которая использует настройку переменных Rails.templates из приведенной выше статьи блога.

Итак, это выглядит следующим образом:

angular.module('myApp').factory('RailsAssetService', function(Rails) {

    function RailsAssetService() {

    }

    RailsAssetService.getAssetsUrl = function(url) {
        var railsUrl = Rails.templates[url];
        if (railsUrl === undefined)
            railsUrl = url;
        return railsUrl;
    }

    return RailsAssetService;
});

и в контроллере:

vm.creditCardsImage = RailsAssetService.getAssetsUrl('credit-cards-logo.gif');

и в представлении:

<img ng-src="{{vm.creditCardsImage}}">
Другие вопросы по тегам