【问题标题】:Angular library: Separate HttpInterceptorAngular 库:单独的 HttpInterceptor
【发布时间】:2020-01-27 21:19:31
【问题描述】:

我想要实现的目标

一个封装的应用程序(表单编辑器),我可以在另一个 Angular 应用程序中使用,也可以在任何 Web 应用程序中使用。


想法

主要模块/组件可以实现为 angular 库(主要组件为 shadow dom),因此我可以添加一个“角度元素”包装器来构建 web 组件,但也可以将库本身作为 npm 包导入我的现有的角度应用程序。所以我的 Angular 应用程序不会加载完整的 javascript 包,而只是加载其他应用程序未提供的模块,以获得更好的性能和集成。


问题

对于来自库的每个请求,我想要一个 http 拦截器来登录/将 jwt 令牌添加到请求标头。当我使用角度元素包装器构建应用程序时(除了导入库和构建 webcomponent 什么都不做),一切正常。当我将它添加到角度应用程序时,拦截器没有按预期工作,因为另一个应用程序也有一个拦截器。我只想将库拦截器封装到库中。所以我想我只需要再次在我的库中导入 HttpClientModule 并获取我自己的实例,因此同一文件中定义的 HTTP_INTERCEPTORS 提供程序知道何时触发。不幸的是,这个想法行不通,两者都在干扰。

AppModule

  • 进口:
    • HttpClientModule(1)
    • CustomLibraryModule
  • 提供者:
    • HTTP_INTERCEPTORS(1)

CustomLibraryModule

  • 进口:
    • HttpClientModule(2)
  • 提供者:
    • HTTP_INTERCEPTORS(2)

在最好的情况下,我想在我的应用程序的延迟加载子模块中导入 CustomLibraryModule。


问题

我是否为这种情况选择了正确的工具?你知道我在获取封装的 http 拦截器时做错了什么吗?

【问题讨论】:

  • 你不能在没有延迟加载的情况下封装一个拦截器。这是一个奇怪的想法,因为我不知道在什么用例下会发现一个跨应用程序有用的库,它将 JWT 添加到我的请求中,但是如果你想这样做,你需要包装 http 服务
  • @bryan60 我认为你可以封装它。但我同意你的第二点:你为什么要对表单库发出 HTTP 请求?如果我在您的源代码中看到它,我将不愿意使用它...
  • @Maryannah 检查拦截器的使用说明:angular.io/api/common/http/HttpInterceptor 拥有“封装”拦截器的唯一方法是在延迟加载模块中......这不是预期/支持的用例,更多的是延迟加载的意外副作用,可能会在未来的版本中中断。否则新的 HttpClientModule 导入将覆盖之前的。
  • @bryan60 哦,好吧,我从未见过。感谢您提供这些信息!
  • 用例:此表单编辑器与后端连接。您可以使用表单添加项目,也可以编辑现有项目。每个字段都保存在模糊中。由于多客户目的,还加载了一些主题数据。此表单编辑器应作为仪表板的一部分集成,但也应作为 Web 组件独立运行,以便在每个系统上独立运行。

标签: angular angular-http-interceptors angular-library angular-elements


【解决方案1】:

经过一番研究,我找到了原因,为什么 CustomLibraryModule 没有使用自己的拦截器,而是使用主应用程序的拦截器。该库使用由 nswag(.NET 后端)生成的 API 类。不幸的是,生成的可注入类被配置为单例,所以每个类都用

@Injectable({ providedIn: 'root' })

我改变了这个配置,现在它们被装饰了

@Injectable()

此外,我在模块的“提供者”部分添加了 API 类。现在使用延迟加载模块的 HttpClient 引用调用其构造函数,并调用正确的拦截器。

由于不了解,我慢慢移到这部分代码。所以最后是我自己的错,但我很感谢你的帮助和澄清。

【讨论】:

  • 这太棒了,很高兴看到你是如何做到的。就像你的拦截器的源代码以及它的引入位置。
【解决方案2】:

现在,您说这个独立的表单编辑器知道您的后端需要 JWT,这是在混淆顾虑。 Web 组件应该不知道您的后端实现。

如果你有一个特定的后端,这个组件的所有实例都应该与之通信,那么你可以导出一个拦截器供任何 Angular 应用程序使用,或者你可以直接在你的代码中封装将 JWT 添加到请求中而不是完全使用拦截器。

另外,如果你在 Angular 之外的应用程序中使用它,你仍然需要 Angular 出现在页面上(参见https://angular.io/guide/elements

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 2021-08-03
    相关资源
    最近更新 更多