Ответ 1
1. Проблема круговой зависимости.
Итак, почему появляется ошибка? Вот краткий обзор процесса:
- $http запрашивается.
- $httpProvider просят его создать.
- Во время строительства вы регистрируете перехватчик, который запрашивает еще $http-службу.
- Вы получаете ошибку "Круговая зависимость".
Первое решение.
Создайте свою зависимость, используя angular.injector(). Обратите внимание, что вы создадите еще одну службу $http, независимо от вашего приложения.
$httpProvider.interceptors.push(function($q) {
$injector = angular.injector();
return {
response: function(response) {
$injector.invoke(function($http) {
// This is the exterior $http service!
// This interceptor will not affect it.
});
}
};
});
Второе решение (лучше).
Внесите $инжектор в ваш перехватчик и используйте его для получения зависимостей после инициализации $http, прямо в то время, когда вы в них нуждаетесь. Эти зависимости являются зарегистрированными службами вашего приложения и не будут созданы заново!
$httpProvider.interceptors.push(function($q, $injector) {
return {
response: function(response) {
$injector.invoke(function($http, someService) {
// $http is already constructed at the time and you may
// use it, just as any other service registered in your
// app module and modules on which app depends on.
});
}
};
});
2. Проблема предотвращения перехвата.
Если вы используете второе решение, есть две проблемы:
- Если вы используете службу $http внутри своего перехватчика, вы можете закончиться бесконечными перехватами: вы отправляете запрос, перехватчик улавливает его, отправляет другого, ловит другого, отправить еще раз и т.д.
- Иногда вам нужно просто запретить перехват запроса.
Параметр 'config' службы $http - это всего лишь объект. Вы можете создать соглашение, предоставить настраиваемые параметры и распознать их в своих перехватчиках.
Например, добавьте свойство "nointercept" в конфигурацию и попробуйте дублировать каждый запрос пользователя. Это глупое приложение, но полезный пример для понимания поведения:
$httpProvider.interceptors.push(function($q, $injector) {
return {
response: function(response) {
if (response.config.nointercept) {
return $q.when(response); // let it pass
} else {
var defer = $q.defer();
$injector.invoke(function($http) {
// This modification prevents interception:
response.config.nointercept = true;
// Reuse modified config and send the same request again:
$http(response.config)
.then(function(resp) { defer.resolve(resp); },
function(resp) { defer.reject(resp); });
});
return defer.promise;
}
}
};
});
После тестирования свойства в перехватчике вы можете предотвратить перехват в контроллерах и службах:
app.controller('myController', function($http) {
// The second parameter is actually 'config', see API docs.
// This query will not be duplicated by the interceptor.
$http.get('/foo/bar', {nointercept: true})
.success(function(data) {
// ...
});
});