基于环境提供的Angular 5 Http拦截器

7

我在我的angular-cli(v1.5.1,angular v5)应用程序中有以下两个环境:

  1. dev
  2. prod

Dev使用我提供的http-interceptor模拟数据。 Pro使用实时rest api。

如何在dev上提供http-interceptor,但不在pro上提供? 我已经尝试了以下方法,但它不起作用:

{
  provide: HTTP_INTERCEPTORS,
  useFactory: () => {
    if (environment.useMockBackend === true) {
      return MockHttpInterceptor;
    }
    return false;
  },
  multi: true
}
3个回答

8
在我的Angular 5.2项目中,我采用了以下方法。 app.module.ts
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { environment } from '../environments/environment';
import { MyInterceptor } from './my.interceptor';

const commonProviders = [/*...*/];
const nonProductionProviders = [{ 
  provide: HTTP_INTERCEPTORS,
  useClass: MyInterceptor,
  multi: true
}];

@NgModule({
  imports: [
    HttpClientModule,
    // ...
  ],
  providers: [
    ...commonProviders,
    ...!environment.production ? nonProductionProviders : []
  ]
})

my.interceptor.ts

import { Injectable } from '@angular/core';
import { HttpEvent, HttpRequest, HttpInterceptor, HttpHandler } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class MyInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    // ...
    return next.handle(req);
  }
}

4

我想到了以下方法(这是在Angular 7中),参考了之前@dhilt和@kemsky的回答:

您的开发环境文件

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { MyDevInterceptor} from './my-dev.interceptor';

export const ENVIRONMENT_SPECIFIC_PROVIDERS = [
  { provide: HTTP_INTERCEPTORS, useClass: MyDevInterceptor, multi: true }
];

environment.prod.ts

export const ENVIRONMENT_SPECIFIC_PROVIDERS = [];

app.module.ts

@NgModule({
  declarations: [],
  imports: [
    HttpClientModule
  ],
  providers: [
    ENVIRONMENT_SPECIFIC_PROVIDERS
  ]
})

这很简单,它可以很好地发挥作用,并且意味着您的代码库不包含任何与您的环境无关的内容。


我在环境中指定了一些常量,它们在 HttpInterceptor 中被使用。当我按照你的示例实现时,会出现循环依赖警告。 - Nuryagdy Mustapayev
猜想你需要找其他地方来存放那些常量,@NuryagdyMustapayev!或者使用不同的方法... - Dan King
@DanKing,那么app.module.ts中的ENVIRONMENT_SPECIFIC_PROVIDERS应该从environment.ts或environment.prod.ts中导入? - Mitul Panchal
@MitulPanchal,你永远不会直接导入environment.prod.ts - 你总是导入environment.ts。然后根据angular.json文件中的配置,在构建时进行替换。请参见https://angular.io/guide/build#configuring-application-environments。 - Dan King

2
这个想法是从环境文件中导出拦截器提供者。在生产环境中,导出一个不执行任何操作的拦截器或其他虚拟提供者(我们称之为 DefaultHttpInterceptor),而在开发环境中,则导出 MockHttpInterceptor。
开发环境:export const INTERCEPTORS = {provide: HTTP_INTERCEPTORS, ... MockHttpInterceptor} 生产环境:export const INTERCEPTORS = {provide: HTTP_INTERCEPTORS, ... DefaultHttpInterceptor} 然后您可以像往常一样使用它:
import { INTERCEPTORS } from './../environments/environment';
@NgModule({
providers      : [
        ...
        INTERCEPTORS 
        ...
    ]
...
})

谢谢您的帮助,但我遇到了以下错误:ERROR TypeError: this.interceptor.intercept不是一个函数 - StefanN
也许应该是 return new MockHttpInterceptor(); 吗? - kemsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接