AngularJS拦截器:如何设置responseError值全局复用及处理420状态码?
AngularJS拦截器两个常见问题的解决方案
嘿,我来帮你搞定这两个AngularJS拦截器的问题,这俩场景在实际项目里真的挺常见的,咱们一个个捋清楚:
一、在responseError中设置共享值供所有请求复用
要让所有请求都能复用responseError里设置的值,核心思路是利用AngularJS的单例服务来存储这个值——因为服务在整个应用生命周期里只有一个实例,所有组件、请求都能访问到它。
步骤1:创建一个共享数据服务
先写一个简单的单例服务,用来存咱们需要共享的内容:
angular.module('yourApp').factory('SharedRequestData', function() { var sharedData = { globalErrorValue: null // 这里存要共享的值 }; return { getGlobalValue: function() { return sharedData.globalErrorValue; }, setGlobalValue: function(value) { sharedData.globalErrorValue = value; } }; });
步骤2:在拦截器中注入并使用这个服务
在你的responseError拦截器里,注入这个服务,把需要共享的值存进去:
angular.module('yourApp').factory('HttpInterceptor', function(SharedRequestData, $q) { return { responseError: function(rejection) { // 比如你想把某个错误信息或者状态码存起来 if (rejection.status === 500) { SharedRequestData.setGlobalValue('服务器内部错误,请稍后重试'); } // 别忘了返回被拒绝的promise,让后续流程正常处理 return $q.reject(rejection); } }; });
步骤3:在其他请求或组件中复用这个值
不管是在另一个拦截器、控制器还是服务里,只要注入SharedRequestData,就能拿到这个共享值:
// 比如在某个控制器里 angular.module('yourApp').controller('SomeController', function(SharedRequestData) { var errorMsg = SharedRequestData.getGlobalValue(); console.log(errorMsg); // 就能拿到responseError里设置的值 });
二、处理420状态码:拦截老用户重置密码期间的所有请求
这个需求需要咱们做两件事:检测420状态码并跳转重置页面,以及在重置完成前拦截所有新请求。同样可以用上面的共享服务来管理状态。
步骤1:扩展共享服务,增加状态标志
更新刚才的SharedRequestData,加一个标志来记录是否需要重置密码:
angular.module('yourApp').factory('SharedRequestData', function() { var sharedData = { globalErrorValue: null, isPasswordResetRequired: false // 新增:标记是否需要重置密码 }; return { getGlobalValue: function() { return sharedData.globalErrorValue; }, setGlobalValue: function(value) { sharedData.globalErrorValue = value; }, isResetRequired: function() { return sharedData.isPasswordResetRequired; }, setResetRequired: function(status) { sharedData.isPasswordResetRequired = status; } }; });
步骤2:在拦截器中处理420和请求拦截
现在要给拦截器加两个部分:responseError处理420跳转,request拦截未完成重置时的请求:
angular.module('yourApp').factory('HttpInterceptor', function(SharedRequestData, $q, $location) { return { // 拦截请求:如果需要重置密码,直接拒绝请求 request: function(config) { // 给重置密码API开白名单,避免拦截它本身 if (SharedRequestData.isResetRequired() && config.url !== '/api/reset-password') { // 拒绝请求,避免无效调用 return $q.reject({reason: 'Password reset required'}); } return config; }, // 处理响应错误:检测420状态码 responseError: function(rejection) { if (rejection.status === 420) { // 设置重置密码标志 SharedRequestData.setResetRequired(true); // 跳转到密码重置页面,避免重复跳转 if ($location.path() !== '/reset-password') { $location.path('/reset-password'); } } return $q.reject(rejection); } }; });
步骤3:重置密码完成后恢复状态
当用户在重置页面完成密码重置后,记得把标志改回来,这样后续请求就能正常发送了:
angular.module('yourApp').controller('ResetPasswordController', function(SharedRequestData, $location) { this.resetPassword = function() { // 调用重置密码的API逻辑... // 假设重置成功后: SharedRequestData.setResetRequired(false); $location.path('/dashboard'); // 跳回正常页面 }; });
额外提示
- 如果你担心多个请求同时触发420导致多次跳转,代码里的
$location.path()判断已经能避免这个问题。 - 可以根据实际需求扩展白名单,比如把登录、验证码等必要接口也加入放行列表。
内容的提问来源于stack exchange,提问作者uncommon_breed
相关产品推荐
相关产品推荐

