博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
$httpprovider指令中拦截器interceptors的使用介绍
阅读量:6983 次
发布时间:2019-06-27

本文共 6514 字,大约阅读时间需要 21 分钟。

hot3.png

$http服务允许我们使用http请求和后台做通信,但是在每一次放松请求之前我们都希望能够捕捉这个请求并且进行操作,比如之前富瑞中每一个请求中header要放入用户名和密码一样,富瑞的做法是放了一个全局变量,但是这个方法是非常不可取的!全部变量污染的问题,所以在angularjs指令中的拦截器就是个很好的解决方案!然后对于http请求的一些服务也可以有一个很好的统一的处理方法

下面具体说下$httpprovider中的interceptors,下面称之为拦截器

其实也就是$httpprovider服务包含一个拦截器数组,是一个简单的factory注册进来的。

创建拦截器:

写一个factory

angular.module('pldApp.services', [])  .factory('authInterceptor',function () {    return {      request: function (config) {        config.headers = config.headers || {};          var token = JSON.parse(window.localStorage.getItem("token")) || "";          config.headers.Authorization = 'Bearer ' + token.access_token;        return config;      }    };  });

config里面配置

$httpProvider.interceptors.push('authInterceptor');

然后在每一次发送请求的时候都调用request方法,这里我打印了config的具体信息,其实这里大家可以看到请求的具体内容,然后我们可以在他发送请求之前大肆的改动请求的内容。225432_nGbb_2491705.png

这里我用的是request方法

拦截器允许有一下四个操作:
1、 请求的拦截:request
这个方法的调用在$http请求之前
所以在此之前我们可以修改配置和进行其他操作!
2、 拦截响应:response
当$http服务收到后台给出响应的时候,这个方法被调用。所以我们可以修改请求响应。这个方法接受一个响应对象作为参数。响应对象包含请求配置、标题、状态以及从后台返回的数据。如果返回的是一个无效的对象或者是promise,这个是不会调用的。
3、 拦截请求错误:requestError
4、 拦截响应错误:responseError
这里注意拦截响应错误!!!当你的controller这么写的时候

$scope.getLogin = function(){  $scope.myLoading();  loginService.getLogin($scope.user.name,$scope.user.paw).success(function(data){    window.localStorage.setItem("token",JSON.stringify(data));    window.localStorage.setItem("username",$scope.user.name);    window.localStorage.setItem("password",$scope.user.paw);    //获取用户信息    loginService.getUserInfo().success(function(data){      mineService.setInifo(data);    }).error(function(status,error){      $ionicLoading.show({        template:chargeStatus(status)      });    });    $scope.lodingHide();    $scope.skipPage('tab.homePage');  }).error(function(error,status){    $ionicLoading.show({      template:chargeStatus(status)    });    $timeout(function () {      $ionicLoading.hide();    },2000);  });};

如果登录名和密码错误了,但是你依旧这么封装responseError的话,controller会执行成功毁掉函数的225602_ICod_2491705.png

所以这里我们其实需要自己重新封装个promise的,这样才能够让controller中执行失败的回调函数。

所以上面三个我的写法是这样的

angular.module('pldApp.services', [])  .factory('authInterceptor',function ($q) {    return {      request: function (config) {        config.headers = config.headers || {};          var token = JSON.parse(window.localStorage.getItem("token")) || "";          config.headers.Authorization = 'Bearer ' + token.access_token;        return config;      },      response: function(response) {        console.log("response:");        console.log(response);        return response;      },      responseError:function(errorReason){        console.log(errorReason);        return $q.reject(errorReason);      },      requestError:function(errorReason){        console.log(2);        return $q.reject(errorReason);      }    };  });

因为这个我也接触的不是特别深入,所以这里给大家只是简单的介绍了下基本用法

下面是从网上找的一些引用:

异步操作:

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;        }    };    return requestInterceptor;}]);

Session 拦截器

现在创建一个get请求:

$http.get('https://api.github.com/users/naorye/repos');

被之前的配置对象 sessionInjector :

{    "transformRequest": [        null    ],    "transformResponse": [        null    ],    "method": "GET",    "url": "https://api.github.com/users/naorye/repos",    "headers": {        "Accept": "application/json, text/plain, */*"    }}

配置对象 sessionInjector :

{    "transformRequest": [        null    ],    "transformResponse": [        null    ],    "method": "GET",    "url": "https://api.github.com/users/naorye/repos",    "headers": {        "Accept": "application/json, text/plain, */*",        "x-session-token": 415954427904    }}

请求恢复拦截器:

module.factory('requestRejector', ['$q', function($q) {      var requestRejector = {        request: function(config) {            return $q.reject('requestRejector');        }    };    return requestRejector;}]);module.factory('requestRecoverer', ['$q', function($q) {      var requestRecoverer = {        requestError: function(rejectReason) {            if (rejectReason === 'requestRejector') {                // Recover the request                return {                    transformRequest: [],                    transformResponse: [],                    method: 'GET',                    url: 'https://api.github.com/users/naorye/repos',                    headers: {                        Accept: 'application/json, text/plain, */*'                    }                };            } else {                return $q.reject(rejectReason);            }        }    };    return requestRecoverer;}]);module.config(['$httpProvider', function($httpProvider) {      $httpProvider.interceptors.push('requestRejector');    // Removing 'requestRecoverer' will result to failed request    $httpProvider.interceptors.push('requestRecoverer'); }]);

Session recover拦截器的使用

module.factory('sessionRecoverer', ['$q', '$injector', function($q, $injector) {      var sessionRecoverer = {        responseError: function(response) {            // Session has expired            if (response.status == 419){                var SessionService = $injector.get('SessionService');                var $http = $injector.get('$http');                var deferred = $q.defer();                // Create a new session (recover the session)                // We use login method that logs the user in using the current credentials and                // returns a promise                SessionService.login().then(deferred.resolve, deferred.reject);                // When the session recovered, make the same backend call again and chain the request                return deferred.promise.then(function() {                    return $http(response.config);                });            }            return $q.reject(response);        }    };    return sessionRecoverer;}]);module.config(['$httpProvider', function($httpProvider) {      $httpProvider.interceptors.push('sessionRecoverer');}]);

这里就是说道了,要重新封装promise。

这一块其实我也只是刚刚踏入了解,如果后续大家有研究,可以互相讨论讨论!

说到这,是不是发现$q很有搞头?!有必要研究下?!

转载于:https://my.oschina.net/Nealyang/blog/603692

你可能感兴趣的文章
(实践篇)剖析最近项目使用的一个框架
查看>>
tigerVNC的简单使用教程(CentOS的远程桌面连接)
查看>>
组合数据类型综合练习:英文词频统计
查看>>
文献综述八:基于JAVA的商品网站的研究
查看>>
iOS 应用有用户评论功能 因为潜在色情信息被退回解决方案
查看>>
usaco Typo
查看>>
DataTable 实现新增加合计行
查看>>
字符串
查看>>
创建对象的三种方式
查看>>
spring学习之spring 插件 for eclipse
查看>>
js-sha256源码
查看>>
运维笔试题
查看>>
dispaly、position、float之间的关系与相互作用
查看>>
MyEclipse加入jquery.js文件missing semicolon的错误
查看>>
axis1.4生成客户端
查看>>
MI-NOTE黑砖
查看>>
WinForm中Component Class、User Control及Custom Control的区别和使用建议
查看>>
地区选择控件杂记
查看>>
来自工程师的8项Web性能提升建议
查看>>
dns配置文件
查看>>