宝哥软件园

详细解释Angular.js中$http拦截器的引入和使用

编辑:宝哥软件园 来源:互联网 时间:2021-09-04

Angular中使用了$http服务来简化与后台的交互过程,它本质上是使用XMLHttpRequest或JSONP与后台数据进行交互。在与后台交互的过程中,每一个请求都可能在发送到服务器之前进行预处理(比如添加令牌),或者在服务器返回的数据到达客户端还没有处理之前进行预处理(比如转换非JSON格式的数据);当然,也可以捕获在请求和响应过程中出现的问题。所有这些需求在开发中非常常见,因此Angular为我们提供了$http拦截器来满足上述需求。

什么是拦截器

顾名思义,拦截器在目标到达目的地之前对其进行处理,这样处理的结果更符合我们的预期。Angular的$http拦截器是由$ httprovider .拦截器数组定义的一组拦截器,每个拦截器都是一个Factory:它实现了一些特定的方法

实现拦截器

Http拦截器通常通过定义工厂来实现:

Myapp.factory ('myinterceptor ',函数($ q){ return {//可选,截取成功的请求request:函数(config){//prepare//.返回config | | $ q . when(config);},//可选,拦截失败的请求错误:函数(拒绝){//处理失败的请求/.if(can recover(reject)){ return response ornewpolice } return $ q . reject(reject);},//可选,截取成功响应response:函数(response){//prepare///.返回响应| | $ q.when(响应);},//可选,拦截失败响应响应错误:函数(拒绝){//处理失败响应//.if(can recover(reject)){ return response ornewpolice } return $ q . reject(reject);} };});然后,我们需要将实现的拦截器添加到$ httprovider .拦截器数组中,这通常在config方法中完成:

myApp.config(函数($ httprovider){ $ httprovider . interceptors . push(my interceptor);});当然,我们也可以通过匿名事实来实现:

$ httprovider . interceptors . push(function($ q){ return { request : function(config){//Bala },response : function(response){//Bala },//Bala };});可以看到,每个拦截器可以实现四个可选的处理功能,分别对应于请求的拦截(成功/失败)和响应(成功/失败):

1.request:在$http向服务器发送请求之前调用该函数。在这个函数中,可以处理成功的http请求,它包含一个http config对象作为参数。在这里,config对象具有完整的处理权限,甚至可以被重构,然后可以直接返回或者返回包含该对象的承诺。如果返回错误,$http请求将失败。如果在开发过程中经常向请求头中添加令牌来验证身份,我们可以执行以下操作:

request:函数(config){ config . headers=config . headers | | { };if($ window . sessionstorage . Token){ config . headers[' X-Access-Token ']=$ window . sessionstorage . Token;}返回config | | $ q . when(config);}2.requestError:当前一个拦截器抛出异常或拒绝操作时,将调用此方法。这里可以执行恢复请求的操作,也可以执行一些请求时发起动作的处理(比如取消加载等)。);

3.response:当$http收到来自服务器的响应时,调用该函数。在这个函数中,可以处理成功的HTTP响应。在这里,响应可以被完全处理,甚至重构,然后可以直接返回响应或者返回包含响应的承诺。如果返回错误,$http将无法接收响应;

4.responseError:当前一个拦截器抛出异常或拒绝时,将调用此方法。在这里,您可以恢复响应并处理一些错误。

用例

为了演示Angular $http拦截器的使用,以下示例用于说明:

利用请求拦截器仿真实现角度XSRF (CSRF)防御

CSRF是“跨站点请求伪造”,但我不知道Angular为什么称之为XSRF。在处理与后台的交互时,Angular $http将尝试从客户端cookie中读取一个令牌,该令牌的默认密钥是XSRF-TOKEN,并构造一个名为X-XSRF-TOKEN的http头,该头将与http请求一起发送到后台。服务器端可以根据这个token识别请求来自同一个域,当然跨域请求$http不会被添加到X-XSRF-TOKEN头中。然后我们可以使用请求拦截器将这个头按照以下方式添加到同一个域请求头中,达到模拟Angular XSRF (CSRF)防御机制的实现效果:

/* * *在正式开发中,Angular会主动防御XSRF(只要cookies中有一个密钥为‘XSRF-TOKEN’的令牌),*一般不需要手动做这个,除非cookies中没有密钥为‘XSRF-TOKEN’的令牌。这只是*/request : function(config){ if(config . URL . indexof(' same _ domain _ API _ URL ')-1){ config . headers[' x-xsrf-token ']=$ cookies . get(' xsrf-token ');}返回配置;}如果初始http请求头类似于:

headers ' : { ' accept ' : ' application/JSON,text/plain,*/* }然后通过上面的拦截器后,它的http请求头变成:

headers ' : { ' accept ' : ' application/JSON,text/plain,*/*,' x-xsrf-token ' : x-xsrf-token-value }使用响应拦截器模拟实现Angular JSON漏洞防御

Angular不仅在$http请求安全方面为我们设计了XSRF(CSRF)防御,还针对请求JSON数据的Url可能被恶意网站以类似脚本标签加载的方式获取的情况,设计了Angular JSON漏洞防御。也就是说,')]} ',n '字符串可以添加到服务器返回的JSON数据头中。获得包含此前缀的响应数据后,Angular将删除此前缀,并将响应恢复为正式的JSON数据。此时,我们可以通过响应拦截器来模拟这个过程:

response:函数(response) { var data=审查员响应(response);//假设有这样一个方法if(!data){ response=validateJSONResponse(响应);//假设有这样一个方法}返回response | | $ q . when(report);}使用请求拦截器和响应拦截器计算http请求的时间消耗

这一要求在开发中可能不常用。这只是同时使用请求拦截器和响应拦截器的一个例子。我们可以分别对请求拦截器和响应拦截器进行计时,然后找出区别:

myApp.factory('timestampMarker ',[function(){ return { request : function(config){ config . request timestamp=new Date()。getTime();返回配置;},response:函数(响应){ response . config . responsetimestamp=new Date()。getTime();返回响应;} };}]);myapp . config([' $ Httprevider ',function($ Httprevider){ $ Httprevider . interceptors . push(' timestampMarker ');}]);这样,每次我们请求后台时,就可以计算出相应请求的时间消耗,比如:

$ http . get(' https://API . github.com/users/刘文庄/回购')。然后(function(response){ var time=response . config . responsettimestamp-response . config . request timestamp;console.log('请求耗时'(时间/1000)'秒');});摘要

作为Angular中的核心服务,$http非常强大和方便。今天,描述它的子功能HTTP拦截器的概念和描述。有一些不正确的理解。请留言告知。

更多资讯
游戏推荐
更多+