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

Angular拦截器注入myService报错,如何正确实现服务注入?

在AngularJS HTTP拦截器中注入自定义服务的正确姿势

当然允许在拦截器里使用自定义服务,但你碰到的[$injector:unpr]错误,本质是循环依赖导致的——这是AngularJS注入机制里的常见坑。

错误原因分析

你的ErrorResponseInterceptor依赖myService,但myService本身又注入了$http;而$http在初始化时会依赖所有已注册的HTTP拦截器(包括你的ErrorResponseInterceptor),这就形成了一个闭环:
ErrorResponseInterceptor → myService → $http → ErrorResponseInterceptor
AngularJS的注入器没法在初始化阶段解析这种循环依赖,所以抛出了“未知提供者”的错误。

正确解决方案:延迟注入

不要直接在拦截器的依赖列表里声明myService,而是利用已经注入的$injector,在需要使用myService的运行时场景中再去获取它,以此打破循环依赖链。

修改后的拦截器代码

(function() { 
  'use strict'; 

  angular.module('sbApp')
    .factory('ErrorResponseInterceptor', ErrorResponseInterceptor)
    .config(ErrorResponseInterceptorConfig); 

  ErrorResponseInterceptorConfig.$inject = [ '$httpProvider' ]; 
  // 移除myService,只保留核心依赖
  ErrorResponseInterceptor.$inject = [ '$rootScope', '$q', '$injector']; 

  function ErrorResponseInterceptorConfig($httpProvider) { 
    $httpProvider.interceptors.push('ErrorResponseInterceptor'); 
  } 

  function ErrorResponseInterceptor($rootScope, $q, $injector) { 
    return {
      // 示例:在响应错误处理中延迟获取myService
      responseError: function(rejection) {
        // 运行时通过$injector获取myService实例
        const myService = $injector.get('myService');
        
        // 在这里执行你需要的业务逻辑,比如调用myService的方法
        // 例如:myService.add('errorModule', rejection);
        
        return $q.reject(rejection);
      },
      // 如果有成功响应的处理,同样在内部延迟注入
      response: function(response) {
        // 按需获取myService
        // const myService = $injector.get('myService');
        return response;
      }
    };
  } 
})();

为什么这样有效?

$injector.get()是在代码运行到具体逻辑时才去解析并获取myService的实例,而不是在拦截器初始化阶段就尝试解析所有依赖。这就避开了初始化时的循环依赖闭环,让AngularJS可以正常完成各服务的实例化。

内容的提问来源于stack exchange,提问作者Prashant

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:36:42