angular .module('app') .factory('HttpInterceptor', ['$q', HttpInterceptor]); function HttpInterceptor($q) { return { // 请求发出之前,可以用于添加各种身份验证信息 request: function(config){ if(localStorage.token) { config.headers.token = localStorage.token; } return config; }, // 请求发出时出错 requestError: function(err){ return $q.reject(err); }, // 成功返回了响应 response: function(res){ return res; }, // 返回的响应出错,包括后端返回响应时,设置了非 200 的 http 状态码 responseError: function(err){ return $q.reject(err); } }; }
拦截器提供了对发出请求到返回响应的全生命周期处理,一般可以用来做下面几个事情:
1.统一在发出的请求中添加数据,如添加身份验证信息
2.统一处理错误,包括请求发出时出的错(如浏览器端的网络不通),还有响应时返回的错误
3.统一处理响应,比如缓存一些数据等
4.显示请求进度条
在上面的示例代码中,当 localStorage 中包括 token 这个值时,就在每一个请求的头部,添加一个 token 值。
失效及处理
一般的,后端应该在 token 验证失败时,将响应的 http 状态码设置为 401 ,这样,在拦截器的 responseError 中便可以统一处理:
responseError: function(err){ if(-1 === err.status) { // 远程服务器无响应 } else if(401 === err.status) { // 401 错误一般是用于身份验证失败,具体要看后端对身份验证失败时抛出的错误 } else if(404 === err.status) { // 服务器返回了 404 } return $q.reject(err); }
总结
其实,只要服务器返回的状态码不是 200 ,都会调用 responseError ,可以在这里,统一处理并显示错误。