You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:53:27