$http服务容许咱们使用http请求和后台作通讯,可是在每一次放松请求以前咱们都但愿可以捕捉这个请求而且进行操做,好比以前富瑞中每个请求中header要放入用户名和密码同样,富瑞的作法是放了一个全局变量,可是这个方法是很是不可取的!所有变量污染的问题,因此在angularjs指令中的拦截器就是个很好的解决方案!而后对于http请求的一些服务也能够有一个很好的统一的处理方法git
下面具体说下$httpprovider中的interceptors,下面称之为拦截器
其实也就是$httpprovider服务包含一个拦截器数组,是一个简单的factory注册进来的。angularjs
建立拦截器:
写一个factorygithub
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里面配置json
$httpProvider.interceptors.push('authInterceptor');
而后在每一次发送请求的时候都调用request方法,这里我打印了config的具体信息,其实这里你们能够看到请求的具体内容,而后咱们能够在他发送请求以前大肆的改动请求的内容。api
这里我用的是request方法
拦截器容许有一下四个操做:
一、 请求的拦截:request
这个方法的调用在$http请求以前
因此在此以前咱们能够修改配置和进行其余操做!
二、 拦截响应:response
当$http服务收到后台给出响应的时候,这个方法被调用。因此咱们能够修改请求响应。这个方法接受一个响应对象做为参数。响应对象包含请求配置、标题、状态以及从后台返回的数据。若是返回的是一个无效的对象或者是promise,这个是不会调用的。
三、 拦截请求错误:requestError
四、 拦截响应错误: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会执行成功毁掉函数的promise
因此这里咱们其实须要本身从新封装个promise的,这样才可以让controller中执行失败的回调函数。session
因此上面三个个人写法是这样的app
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颇有搞头?!有必要研究下?!