Принудительный перехватчик 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}}">