Захват HTTP-перехватчика в динамическом запросе ngSrc
Я создал приложение AngularJS, которое загружает изображения из защищенного брандмауэра OAuth. Моя библиотека OAuth настроена путем добавления дополнительного перехватчика к Angular $httpProvider
для добавления правильного заголовка проверки подлинности.
Мой исходный код в моем шаблоне HTML
выглядит следующим образом:
<img ng-src="{{ '/users/1/images/' + imageId }}">
Моя проблема заключается в том, что HTTP-запрос, созданный директивой ngSrc
, игнорируется реализацией $http
, что приводит к запросу с неправильной аутентификацией.
Нормальные функции API-вызовов функционируют корректно (те, которые вызываются моими контроллерами/службами, напрямую используя $http
и $resource
).
Ответы
Ответ 1
Директива ngSrc
просто управляет обычным атрибутом src
для img, что заставляет браузер запрашивать изображение так же, как и любое другое изображение, а не через Javascript, поэтому я не думаю, что это может быть перехвачено.
Однако, что вы могли бы сделать, написать новую директиву, сохранить httpSrc. Затем он может получить изображение с помощью вызова $http
, а затем создать URI данных с ответом, используя что-то вроде Использование необработанных данных изображения из запроса ajax для URI данных (хотя я не уверен в поддержке браузера).
Ответ 2
На основании ответа Михала директива может выглядеть следующим образом
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">
Ответ 3
Как сказано здесь, вы можете использовать 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}}">
Ответ 4
Это немного старо, но я подумал, что добавлю еще один метод поиска изображения без использования перехватчика. В моем случае мне нужно было найти путь изображения из конвейера ресурсов рельсов.
Был блог от 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}}">