前言

$http service在Angular中用于简化与后台的交互过程,其本质上使用XMLHttpRequest或JSONP进行与后台的数据交互。在与后台的交互过程中,可能会对每条请求发送到Server之前进行预处理(如加入token),或者是在Server返回数据到达客户端还未被处理之前进行预处理(如将非JSON格式数据进行转换);当然还有可能对在请求和响应过程过发生的问题进行捕获处理。所有这些需求在开发中都非常常见,所以Angular为我们提供了$http拦截器,用来实现上述需求。
什么是拦截器
顾名思义,拦截器就是在目标达到目的地之前对其进行处理以便处理结果更加符合我们的预期。Angular的$http拦截器是通过$httpProvider.interceptors数组定义的一组拦截器,每个拦截器都是实现了某些特定方法的Factory:
实现拦截器
http拦截器一般通过定义factory的方式实现:
myApp.factory('MyInterceptor', function($q) {
return {
// 可选,拦截成功的请求
request: function(config) {
// 进行预处理
// ...
return config || $q.when(config);
},
// 可选,拦截失败的请求
requestError: function(rejection) {
// 对失败的请求进行处理
// ...
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
},
// 可选,拦截成功的响应
response: function(response) {
// 进行预处理
// ....
return response || $q.when(reponse);
},
// 可选,拦截失败的响应
responseError: function(rejection) {
// 对失败的响应进行处理
// ...
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
}
};
});
随后,我们需要将实现的拦截器加入到$httpProvider.interceptors数组中,此操作一般在config方法中进行:
myApp.config(function($httpProvider) {
$httpProvider.interceptors.push(MyInterceptor);
});
当然,我们也可以通过匿名factroy的方式实现:
$httpProvider.interceptors.push(function($q) {
return {
request: function(config) {
// bala
},
response: function(response) {
// bala
},
// bala
};
});
可以看到,每个拦截器都可以实现4个可选的处理函数,分别对应请求(成功/失败)和响应(成功/失败)的拦截:
1、request:此函数在$http向Server发送请求之前被调用,在此函数中可以对成功的http请求进行处理,其包含一个http config对象作为参数,这里对config对象具有完全的处理权限,甚至可以重新构造,然后直接返回此对象或返回包含此对象的promise即可。如果返回有误,会造成$http请求失败。如开发中经常需要在请求头中加入token以便验证身份,我们可以作如下处理:
request: function(config) {
config.headers = config.headers || {};
if ($window.sessionStorage.token) {
config.headers['X-Access-Token'] = $window.sessionStorage.token;
}
return config || $q.when(config);
}
2、requestError:此方法会在前一个拦截器抛出异常或进行了reject操作时被调用,在这里可以进行恢复请求的操作,或者进行一些对于请求时发起动作的处理(如取消loading等);
3、response:此函数在$http从Server接收到响应时被调用,在此函数中可以对成功的http响应进行处理,这里具有对响应的完全处理权限,甚至可以重新构造,然后直接返回响应或返回包含响应的promise即可。如果返回有误,会造成$http接收响应失败;
4、responseError:此方法会在前一个拦截器抛出异常或进行了reject操作时被调用,在这里可以进行恢复响应的操作,进行一些针对错误的处理。
使用用例
为演示Angular $http拦截器的使用方法,下面通过几个常用的用例来说明:
利用request拦截器模拟实现Angular的XSRF(即CSRF)防御
CSRF,即“跨站请求伪造”,不过不知道为什么Angular将其称为XSRF。当处理与后台交互时,Angular的$http会尝试从客户端cookie中读取一个token,其默认的key为XSRF-TOKEN,并构造一个名为X-XSRF-TOKEN的http头部,与http请求一起发送到后台。Server端就可以根据此token识别出请求来源于同域,当然跨域的请求$http不会加入X-XSRF-TOKEN头部。那我们可以利用request拦截器通过如下方式在同域请求头部中加入此头部以达到模拟Angular的XSRF(即CSRF)防御机制的实现效果:
/**
* 正式开发中Angular会主动进行XSRF防御(只要cookie中存在key为`XSRF-TOKEN`的token),
* 一般不需要手动进行,除非cookie中不存在key为`XSRF-TOKEN`的token,这里只是模拟实现
*/
request: function(config) {
if(config.url.indexOf('SAME_DOMAIN_API_URL') > -1) {
config.headers['X-XSRF-TOKEN'] = $cookies.get('XSRF-TOKEN');
}
return config;
}
如果初始http请求头部类似于:
"headers": {
"Accept": "application/json, text/plain, */*"
}
那么经过上述的拦截器后,其http请求头部就变成了:
"headers": {
"Accept": "application/json, text/plain, */*",
"X-XSRF-TOKEN": X-XSRF-TOKEN-VALUE
}
利用response拦截器模拟实现Angular JSON易损性(JSON vulnerability)防御
Angular在$http请求安全性方面不仅为我们设计了XSRF(CSRF)防御,而且针对请求JSON数据的Url可能通过类似于<script>标签加载的方式被恶意网站获取到我们的JSON数据的情况,设计了Angular JSON易损性(JSON vulnerability)防御,即Server端返回的JSON数据头部可以添加")]}',\n"字符串,得到包含此前缀的响应数据后,Angular会将此前缀删去,将响应还原成正式的JSON数据。此时我们就可以通过response拦截器模拟此过程:
response: function(response) {
var data = examineJSONResponse(response); // 假设存在这样一个方法
if(!data) {
response = validateJSONResponse(response); // 假设存在这样一个方法
}
return response || $q.when(reponse);
}
利用request拦截器和response拦截器计算http请求耗时
这个需求可能在开发中并不常用,这里只是作为同时使用request拦截器和response拦截器的例子,我们可以在request拦截器和response拦截器中分别计时,然后求得其差值即可:
myApp.factory('timestampMarker', [function() {
return {
request: function(config) {
config.requestTimestamp = new Date().getTime();
return config;
},
response: function(response) {
response.config.responseTimestamp = new Date().getTime();
return response;
}
};
}]);
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('timestampMarker');
}]);
这样我们在每次请求后台时,就能够计算出相应请求的耗时了,如:
$http.get('https://api.github.com/users/liuwenzhuang/repos').then(function(response) {
var time = response.config.responseTimestamp - response.config.requestTimestamp;
console.log('The request took ' + (time / 1000) + ' seconds.');
});
总结
$http作为Angular中的核心service,其功能非常强大便捷,今天描述了其子功能http拦截器的概念和描述方式,有理解不正确的地方,请大家留言告知。
# angularjs
# http拦截器
# angular
# angular2
# 浅析AngularJs HTTP响应拦截器
# 快速学习AngularJs HTTP响应拦截器
# 详解为Angular.js内置$http服务添加拦截器的方法
# 拦截器
# 可选
# 在这里
# 在此
# 我们可以
# 发送到
# 在前
# 类似于
# 以对
# 抛出
# 进行了
# 就可以
# 都是
# 客户端
# 法会
# 几个
# 是在
# 不需要
# 请大家
# 将其
相关文章:
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
网站网页制作专业公司,怎样制作自己的网页?
中山网站推广排名,中山信息港登录入口?
香港服务器租用费用高吗?如何避免常见误区?
官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站
威客平台建站流程解析:高效搭建教程与设计优化方案
如何在云服务器上快速搭建个人网站?
C++如何编写函数模板?(泛型编程入门)
如何通过.red域名打造高辨识度品牌网站?
建站之星下载版如何获取与安装?
如何用腾讯建站主机快速创建免费网站?
视频网站app制作软件,有什么好的视频聊天网站或者软件?
高防服务器租用指南:配置选择与快速部署攻略
建站主机默认首页配置指南:核心功能与访问路径优化
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?
如何在腾讯云服务器快速搭建个人网站?
制作网页的网站有哪些,电脑上怎么做网页?
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
云南网站制作公司有哪些,云南最好的招聘网站是哪个?
定制建站哪家更专业可靠?推荐榜单揭晓
香港网站服务器数量如何影响SEO优化效果?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
Swift开发中switch语句值绑定模式
如何高效配置香港服务器实现快速建站?
湖北网站制作公司有哪些,湖北清能集团官网?
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
广德云建站网站建设方案与建站流程优化指南
网站制作免费,什么网站能看正片电影?
如何快速搭建响应式可视化网站?
建站三合一如何选?哪家性价比更高?
免费公司网站制作软件,如何申请免费主页空间做自己的网站?
网站制作服务平台,有什么网站可以发布本地服务信息?
php json中文编码为null的解决办法
创业网站制作流程,创业网站可靠吗?
成都网站制作报价公司,成都工业用气开户费用?
单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?
如何在建站宝盒中设置产品搜索功能?
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
建站主机如何选?性能与价格怎样平衡?
ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?
南宁网站建设制作定制,南宁网站建设可以定制吗?
上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?
如何选择可靠的免备案建站服务器?
红河网站制作公司,红河事业单位身份证如何上传?
香港服务器WordPress建站指南:SEO优化与高效部署策略
建站之星3.0如何解决常见操作问题?
*请认真填写需求信息,我们会在24小时内与您取得联系。