我想响应拦截器添加到我的$ http服务的错误处理的目的。 拦截器逻辑包括在必要的情况下使用$ HTTP发送错误信息到服务器, 但我不想发送错误消息有关错误邮件的服务器,我的意思是,我想在发送错误信息到服务器禁用我的拦截器。
我的想法是创建一个名为“remote_log”,并把它里面的所有发送错误到服务器所需的代码服务。 当然,这服务将使用$ HTTP服务,并在其依赖列表。
然后添加为拦截到“remote_log”服务的依赖,并且需要将错误发送到服务器时使用的“remote_log”拦截器内。 存在的问题是:
拦截器必须使用$ httpProvider当$ HTTP服务仍不会被实例化/访问来定义,所以,里面的拦截器代码不能是该$ HTTP服务,因为一个“循环依赖”的错误发生的相关性。
我想,我唯一的选择就是创建我的“remote_log”,不使用$ httpProvider配置,同时创造拦截我设置的实例里面的$ HTTP服务的一个单独的实例。 我的问题是:我怎么能这样做? 任何其他的想法?
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服务拦截里面,你可能最终与无限的拦截:你发送请求时,拦截捕获它发送另一个,抓住另一个,再次发送,等等。
- 有时候,你只想要阻止拦截的请求。
$ 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) {
// ...
});
});
我用什么在回答描述,但我用一个工厂的语法,因为与匿名函数没有工作,我真的不知道为什么:
(function(angular){
angular.module('app', [])
.config([
'$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push('Interceptor');
}
])
.factory('Interceptor', [
'$injector',
InterceptorFactory
]);
function InterceptorFactory($injector){
return {
request: function(config) {
var ServiceWithHttp = $injector.get('ServiceWithHttp');
// Use ServiceWithHttp
return config;
}
};
}
}(window.angular));