$http服务允许我们与服务端交互,有时候我们希望在发出请求之前以及收到响应之后做些事情。即http拦截。

$httpProvider包含了一个interceptors的数组。

我们这样创建一个interceptor。

app.factory('myInterceptor', ['$log', function($log){
$log.debug(''); var myInterceptor = {}; return myInterceptor;
}])

接着注册interceptor.

app.config(['$httpProvider', function($httpProvider){
$httpProvider.interceptors.push('myInterceptor');
}])

以下是$http拦截的一些例子。

■ 拦截器中的异步操作

app.factory('myInterceotpr','someAsyncServcie', function($q, someAsyncServcie){
var requestInterceptor = {
request: function(config){
var deferred = %q.defer();
someAsyncService.doAsyncOperation().then(function(){
...
deferred.resolve(config);
}, function(){
...
deferred.resolve(config);
})
return deferred.promise;
}
}; return requestInterceptor;
})

以上,是一个请求拦截,做了一个异步操作,根据异步操作的结果来更新config。

当然也有响应拦截。

app.factory('myInterceptor',['$q', 'someAsyncService', function($q, someAsyncSercice){
var responseInterceptor = {
response: function(response){
var deferred = $q.defer();
someAsyncService.doAsyncOperation().then(function(response){
...
deferred.resolve(response);
}, function(response){
...
deferred.resolve(response);
})
return deferred.promise;
}
};
return responseInterceptor;
}])

■ Session拦截,请求拦截

服务端有2种类型的验证,一个是基于cookie的,一种是基于token的。对于基于token验证,当用户登录,获取一个来自服务端的token,这个token在每一次请求时发送给服务端。

创建一个有关session的injector:

app.factory('sessionInjector',['SessionService', function(SessionService){
var sessionInjector = {
request: function(config){
if(!SessionService.isAnonymous){
config.headers['x-session-token'] = SessionService.token;
}
return config;
}
}; return sessionInjector;
}])

可见,把从服务端返回的token放在了config.headers中。

注册injector:

app.config(['$httpProvider', function($httpProvider){
$httpProvider.interceptors.push('sessionInjector');
}])

发出一个请求:
$http.get('');

拦截前大致是:

{
    "transformRequest":[null],
    "transformResponse":[null],
    "method":"GET",
    "url":"",
    "headers":{
        "Accept": "application/json, text/plain,*/*"
    }
}

拦截后,在headers中多两个一个x-session-token字段:

{
    "transformRequest":[null],
    "transformResponse":[null],
    "method":"GET",
    "url":"",
    "headers":{
        "Accept": "application/json, text/plain,*/*",
        "x-session-token":......
    }
}

■ 时间戳,请求和响应拦截

app.factory('timestampMarker',[function(){
var timestampMarker = {
request:function(config){
config.requestTimestamp = new Date().getTime();
return config;
},
response: function(response){
response.config.responseTimestamp = new Date().getTime();
return config;
}
}; return timestampMarker;
}])

以上,在请求和响应时拦截,在config.requestTimestamp和config.responseTimestamp赋上当前的时间。

注册拦截器:

app.config(['$httpProvider', function($httpProvider){
$httpProvider.interceptors.push('timestampMarker');
}])

然后在运用的时候可以算出请求响应所耗去的时间。

$http.get('').then(function(response){
var time = response.config.responseTime - response.config.requestTimestamp;
console.log('请求耗去的时间为 ' + time);
})

■ 请求错误恢复,请求拦截

模拟一个请求拦截的错误情形:

app.factory('requestRejector',['$q', function($q){
var requestRejector = {
request: function(config){
return $q.reject('requestRejector');
}
};
return requestRejector;
}])

拦截请求错误:

app.factory('requestRecoverer',['$q', function($q){
var requestRecoverer = {
requestError: function(rejectReason){
if(rejectReason === 'requestRejector'){
//恢复请求
return {
transformRequest:[],
transformResponse:[],
method:'GET',
url:'',
headers:{
Accept:'application/json, text/plain, */*'
}
};
} else {
return $q.reject(rejectReason);
}
}
}; return requestRecoverer;
}])

注册拦截器:

app.config(['$httpProvider', function($httpProvider){
$httpProvider.interceptors.push('requestRejector');
$httpProvider.interceptors.push('requestRecoverer');
}])

■ Session错误恢复,响应拦截

app.factory('sessionRecoverer',['$q','$injector',function($q, $injector){
var sessionRecoverer = {
responseError: function(response){
//如果Session过期
if(response.status == 419){
var SessionService = $injector.get('SessionService');
var $http = $injector.get('$http');
var deferred = $q.defer(); //创建一个新的session
SessionService.login().then(deferred.resolve, deferred.reject); return deferred.promise.then(function(){
reutrn $http(response.config);
})
}
return $q.reject(response);
}
}; return sessionRecoverer;
}])

参考资料:http://www.webdeveasy.com/

AngularJS中的http拦截的更多相关文章

  1. Angularjs中的拦截器 (卧槽,好牛逼)

    $httpAngularJS 的 $http 服务允许我们通过发送 HTTP 请求方式与后台进行通信.在某些情况下,我们希望可以俘获所有的请求,并且在将其发送到服务端之前进行操作.还有一些情况是,我们 ...

  2. 在AngularJs中怎么设置请求头信息(headers)及不同方法的比较

    在AngularJS中有三种方式可以设置请求头信息: 1.在http服务的在服务端发送请求时,也就是调用http()方法时,在config对象中设置请求头信息:事例如下: $http.post('/s ...

  3. AngularJS中的身份验证

    欢迎大家指导与讨论 : )  一.  身份验证的意义  首先呢,网络应用的身份验证的意图在于:保护网站中的重要资源.基于某些原因这些资源并不能公开,比如付费资源(交过钱的用户才能上的网络课程),或者一 ...

  4. AngularJS 中利用 Interceptors 来统一处理 HTTP 的错误(reproduce)

    原文:http://chensd.com/2016-03/Angular-Handle-Global-Http-Error-with-Interceptors.html?utm_source=tuic ...

  5. angularJS中XHR与promise

    angularJS应用是完全运行在客户端的应用,我们可以通过angularJS构建一个不需依赖于后端,同时能够实现动态内容和响应的web应用,angularJS提供了将应用与远程服务器的信息集成在一起 ...

  6. angular中的http拦截器Interceptors

    在angularJs中增加了一个对全局的http请求统一做出处理的api--interceptors Interceptors 有两个处理时机,分别是: 其它程序代码执行 HTTP 请求之后,在实际从 ...

  7. AngularJS中get请求URL出现跨域问题

    今天早上帮助同学看了一个AngularJS的问题,主要是请求中出现了跨域访问,请求被阻止. 下面是她给我的代码: <html lang="en" ng-app="m ...

  8. AngularJS 中的Promise --- $q服务详解

    先说说什么是Promise,什么是$q吧.Promise是一种异步处理模式,有很多的实现方式,比如著名的Kris Kwal's Q还有JQuery的Deffered. 什么是Promise 以前了解过 ...

  9. AngularJS中的表单验证

    AngularJS中的表单验证 AngularJS自带了很多验证,什么必填,最大长度,最小长度...,这里记录几个有用的正则式验证 1.使用angularjs的表单验证 正则式验证 只需要配置一个正则 ...

随机推荐

  1. coreseek实战(三):全文搜索在php中应用(使用api接口)

    coreseek实战(三):全文搜索在php中应用(使用api接口) 这一篇文章开始学习在php页面中通过api接口,使用coreseek全文搜索. 第一步:综合一下前两篇文章,coreseek实战( ...

  2. IOS一些好的用户体验设置

    1,下载图片时,如果 用户操作UI,那么就停止子线程,用户停止操作子线程时,开启子线程继续下载. SDWebImage  :专门下载图片. 2,网络请求时.本地要进行一些验证,以减少服务器的压力.

  3. 基本数据类型范围大小&&字节大小

    char -128 ~ +127 short -32767 ~ + 32768 unsigned short 0 ~ 65536 int -2147483648 ~ +2147483647 unsig ...

  4. Bootstrap 基础学习笔记(一)

    排版 (1)标题 Bootstrap标题样式进行了以下显著的优化重置: 1.重新设置了margin-top和margin-bottom的值,  h1~h3重置后的值都是20px:h4~h6重置后的值都 ...

  5. 【Linux】LAMP环境的搭建

    LAMP定义 LAMP指的Linux(操作系统).ApacheHTTP 服务器,MySQL(有时也指MariaDB,数据库软件) 和PHP(有时也是指Perl或Python) 的第一个字母,一般用来建 ...

  6. P1403约数研究

    洛谷1403 约数研究 题目描述 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机"Samuel2"的长时间运算成为了可能.由于在去年一年的辛苦工作 ...

  7. js-DOM-页面元素的兼容性、常用事件、节点

    页面元素的兼容性: 所谓的兼容性指的就是当前浏览器是否支持当前对象的属性或是方法,如果支持就是兼容,如果不支持就是不兼容. 举个例子: /** * 设置页面标签之间的文本内容的兼容性写法 * @par ...

  8. Apache 常用伪静态配置

    1. /a/b?c=d => index.php?_a=a&_m=b&c=d 2. /xxx/detail-yyy.html => index.php?_a=xxx& ...

  9. Python成长笔记 - 基础篇 (四)函数

    1.面向对象:类(class) 2.面向过程:过程(def) 3.函数式编程:函数(def)----python   1.函数:http://egon09.blog.51cto.com/9161406 ...

  10. Android系统的常用权限

    1.ACCES_NETWORK_STATE                       允许应用程序获取网络状态信息的权限 2.ACCESS_WIFI_STATE                   ...