---恢复内容开始---
任何时候如果我们想要为请求添加全局功能,例如身份验证、错误处理等,在请求发送给服务器之前或者从服务器返回时对其进行拦截,是比较好的实现手段。
例如对于身份验证,如果服务器返回401状态码,我们会希望将用户重定向到登录页面。AngularJS通过拦截器提供了一个从全局层面对响应进行处理的途径。拦截器,尽管名字听起来很唬人,实际上是$http服务的基础中间件,用来向应用的业务流程中注入新的逻辑。拦截器的核心是服务工厂(查看第14章获得更多关于服务的信息),通过向$httpProvider.interceptors数组中添加服务工厂,在$httpProvider中进行注册。一共有四种拦截器,两种成功拦截器,两种失败拦截器。
Request
AngularJS通过$http设置对象来对请求拦截器进行调用。它可以对设置对象进行修改,或者创建一个新的设置对象,它需要返回一个更新过的设置对象,或者一个可以返回新的设置对象的promise。
Response
AngularJS通过$http设置对象来对响应拦截器进行调用。它可以对响应进行修改,或者创建一个新的响应,它需要返回一个更新过的响应,或者一个可以返回新响应的promise
requestError
AngularJS会在上一个请求拦截器抛出错误,或者promise被reject时调用此拦截器。
responseError
AngularJS会在上一个响应拦截器抛出错误,或者promise被reject时调用此拦截器
调用模块的.factory()方法来创建拦截器,可以在服务中添加一种或多种拦截器
MyApp.factory('authHttpResponseInterceptor', ["$rootScope", "myCookie", '$q', '$location', "$routeParams", function ($rootScope, myCookie, $q, $location,$routeParams) {
//拦截器配置
return {
request: function (config) {
var url = config.url;
//请求通用配置(添加token)
if(url.indexOf("access/login") != -1 || url.indexOf("access/authorize") != -1){
}else if(myCookie("access_token") !== null){
config.headers['access_token'] = myCookie("access_token");
}else if(url.indexOf("rest/") != -1 ||
(url.indexOf("teacher/") != -1 && url.indexOf(".html") != -1) ||
(url.indexOf("student/") != -1 && url.indexOf(".html") != -1)){
//未登录认证
config.url = "unknown";
}
$rootScope.currUrl = config.url;
return config || $q.when(config);
},
response: function(response){
//本地url权限认证
var browserUrl = $location.path();
var stuUrls = ["/stuexam","/stuquestion","/user/bound"];//学生url定义
var commonUrls = ["/404","/busy","/about","/secure","/user"];//公共url定义
var commonUrlLen = commonUrls.length;
var isCommon = false;//是否是公共url
if(browserUrl == "/"){
isCommon = true;
}else{
for(urlIndex=0;urlIndex<commonUrlLen;urlIndex++){
var uri = commonUrls[urlIndex];
if(browserUrl.indexOf(uri) === 0){
isCommon = true;
break;
}
}
}
if(!isCommon && myCookie("accountType") !== null){
var accountType = myCookie("accountType");
if(accountType == "teacher"){
if(browserUrl.indexOf("/stuexam") === 0 || browserUrl.indexOf("/stuquestion") === 0){
$location.path('404');
}
}else if(accountType == "student"){
if(browserUrl.indexOf("/stuexam") !== 0 && browserUrl.indexOf("/stuquestion") !== 0){
$location.path('404');
}
//验证是否是访问的当前学生的数据
if(browserUrl.indexOf("/stuexam/analysis") === 0 || browserUrl.indexOf("/stuexam/paper") === 0){
var studentId = myCookie("accountId");
if(browserUrl.lastIndexOf("/") != browserUrl.length - 1){
browserUrl = browserUrl.substring(0,browserUrl.length);
}
var urlStuId = browserUrl.substring(browserUrl.lastIndexOf("/")+1);
if(studentId !== urlStuId){//访问非当前学生数据
$location.path('404');
}
}
}
}
return response || $q.when(response);
},
responseError: function(rejection) {
var currUrl = $rootScope.currUrl;
//请求返回异常类型判断
if(currUrl !== null && currUrl == "unknown"){
$location.path('/');
}else if (rejection.status == 401) {
if(rejection.data !== null && (rejection.data.message == "No access_token" ||
rejection.data.message == "Invalid token, token has expired!" || rejection.data.message == "Unknown token!")){
$location.path('/');
}else if(currUrl.indexOf("access/") == -1){
$location.path('404');//.search('returnTo', $location.path());
}
}else if (rejection.status == 404) {
$location.path('404');//.search('returnTo', $location.path());
}else if (rejection.status == 412) {
// if(currUrl.indexOf("register")==-1&&currUrl.indexOf("bind")==-1&&currUrl.indexOf("resetPassword")==-1){
// $location.path('busy');
// }
}else if (rejection.status != 200) {
if(currUrl.indexOf("register")==-1&&currUrl.indexOf("bind")==-1&&currUrl.indexOf("resetPassword")==-1){
$location.path('busy');
}
}
return $q.reject(rejection);
}
};
}])
我们需要使用$httpProvider在.config()函数中注册拦截器:
MyApp.config(['$httpProvider', function ($httpProvider) { //Http Intercpetor to check auth failures for xhr requests $httpProvider.interceptors.push('authHttpResponseInterceptor'); }])
---恢复内容结束---
