前言
在angular框架中,创建团队为使用者进行了ajax请求的封装,并通过$http服务暴露出相关的接口.angular在其官方文档中指出, $http服务底层针对web常见的安全攻击做出了相应的对策,也就是说使用$http服务封装的ajax为使用者提供了更为安全的保障.作为一个框架,保证框架的可用性,适配性是很有必要的. angular在设计,实现中也体现出来了这样的良好风格.我们通常在使用ajax时,有时候希望我们能够在请求发起前或接收到请求后做一些相应的处理工作,比如:在请求发起前,在请求头中添加一下报文段.在请求返回时对一请求处理状态做一些管理,如统一处理404状态等等.angular的$http服务在设计实现时充分考虑到了上述的情况.接下来,我们一起来学习和了解一下如何为$http服务添加拦截器,以及如何在我们自己实现的服务中实现类似的拦截器机制.
什么是拦截器–what are interceptors?
interceptor(拦截器)在服务端框架中属于一种比较常见的机制,如spring,struts2等java框架中拦截器属于基本配置项.拦截器提供了一种机制可以使开发者可以定义在一个action(动作)执行的前后执行的代码,这些代码可以是在一个action执行前阻止其执行的代码,也可以是修改目标动作某些行为的代码.(在aop(aspect-oriented programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。在spring框架中比较常见)
$http服务中的拦截器
查看api或是源码我们可以发现,angular的实现中通过 httpprovider提供了一个名为interceptors的数组.这个数组接受拦截器服务注册,通过过程次的注册最终会形成拦截器链.这样每次在调用http服务的时候,angular都会通过我们定义的拦截点(切面)进行相应的ajax动作修改.理论就不多说了,下面开始进入实战:
angular中如何声明一个拦截器
// interceptor declaration module.factory('httpinterceptor', ['$log', function($log) { $log.debug('$log is here to show you that this is a regular factory with injection'); return { // do something }; }]);
如何将声明的拦截器注册到$http服务中
// add the interceptor to $httpprovider.interceptors module.config(['$httpprovider', function($httpprovider) { $httpprovider.interceptors.push('httpinterceptor'); }]);
通过上面的简单两个步骤,我们基本就完成了http服务的拦截器编写与添加.但是上面的代码片段并不能实际使用,要想真正的实现拦截操作,我们还需要遵循http服务暴露出来的可以进行拦截的点进行相关的代码编写.
$httpprovider暴露了那些可以拦截的点?
对于上面暴露出来的接口使用也是异常的简单的,我们可以像声明一个简单的服务一样声明一个$http服务的拦截器,并交由angular的注入机制去使用我们配置的拦截器.
// 如同声明一个angular服务一样声明一个拦截器 module.factory('sessioninjector', ['authservice', function (authservice){ return { request: function (config){ if (!authservice.isanonymus) { config.headers['x-session-token'] = authservice.token; } return config; } }; }]); // 然后将我们声明的拦截器添加到$httpprovider的拦截器链中,之后的服务注入angular会负责帮我们完善 module.config(['$httpprovider', function ($httpprovider){ $httpprovider.interceptors.push('sessioninjector'); }]);
$http服务拦截器的异步支持
部分场景下,我们希望在拦截器中能够执行一些异步操作.然后依据不同的处理结果进行不同的拦截操作,angularjs在设计的时候也很好的支持了这一特性.angularjs允许我们在拦截的方法中,我们可以返回一个promise对象.如在http服务中,我们如果返回一个promise对象时,http服务将会延迟发起网络请求或是延迟响应请求结果.
module.factory('myinterceptor', ['$q', 'someasyncservice', function($q, someasyncservice) { var requestinterceptor = { request: function(config) { var deferred = $q.defer(); someasyncservice.doasyncoperation().then(function() { // asynchronous operation succeeded, modify config accordingly ... deferred.resolve(config); }, function() { // asynchronous operation failed, modify config accordingly ... deferred.resolve(config); }); return deferred.promise; }, response: function(response) { var deferred = $q.defer(); someasyncservice.doasyncoperation().then(function() { // asynchronous operation succeeded, modify response accordingly ... deferred.resolve(response); }, function() { // asynchronous operation failed, modify response accordingly ... deferred.resolve(response); }); return deferred.promise; } }; return requestinterceptor; }]);
上面的例子中,在请求发起时,如果对应的deferred被拒绝,http请求则会失败(如果进行抓包分析的话,你会发现http请求并没有发起).在请求进行响应时,如果deferred被拒绝,则请求也会失败.(抓包分析,网络请求是有返回的).
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
如对本文有疑问, 点击进行留言回复!!
解决三元运算符 报错“SyntaxError: can''t assign to conditional expression”
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码
分享Angular http interceptors 拦截器使用(推荐)
网友评论