Thêm nhiều bộ chặn HTTP vào ứng dụng Angular


85

Làm cách nào để thêm nhiều bộ chặn HTTP độc lập vào ứng dụng Angular 4?

Tôi đã cố gắng thêm chúng bằng cách mở rộng providersmảng với nhiều hơn một bộ đánh chặn. Nhưng chỉ cái cuối cùng thực sự được thực thi, Interceptor1bị bỏ qua.

@NgModule({
  declarations: [ /* ... */ ],
  imports: [ /* ... */ HttpModule ],
  providers: [
    {
      provide: Http,
      useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
        new Interceptor1(xhrBackend, requestOptions),
      deps: [XHRBackend, RequestOptions],
    },
    {
      provide: Http,
      useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
        new Interceptor2(xhrBackend, requestOptions),
      deps: [XHRBackend, RequestOptions]
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Rõ ràng là tôi có thể kết hợp chúng thành một Interceptorlớp duy nhất và điều đó sẽ hoạt động. Tuy nhiên, tôi muốn tránh điều đó vì những thiết bị đánh chặn này có các mục đích hoàn toàn khác nhau (một để xử lý lỗi, một để hiển thị chỉ báo tải).

Vậy làm cách nào để có thể thêm nhiều bộ đánh chặn?


2
Bạn đang ghi đè Http. Chỉ ghi đè cuối cùng được sử dụng. Interceptor1 không bị bỏ qua, nó chỉ là không tồn tại. Bạn có thể sử dụng HttpClient có bao gồm các bộ đánh chặn.
Estus Flask

@estus Ý bạn là gì khi "Bạn có thể sử dụng HttpClient có bao gồm các bộ chặn."?
str


bạn có thể sử dụng các bộ chặn khác nhau cho yêu cầu, phản hồi bằng cách sử dụng cái này mà bạn có thể xử lý lỗi, chỉ báo bộ tải.
nivas

Có cập nhật nào về câu hỏi này không?
Renil Babu

Câu trả lời:


162

Httpkhông cho phép có nhiều hơn một triển khai tùy chỉnh. Nhưng như @estus đã đề cập, nhóm Angular đã thêm một dịch vụ HttpClient mới gần đây (bản phát hành 4.3) hỗ trợ khái niệm nhiều bộ đánh chặn. Bạn không cần phải mở rộng HttpClientnhư bạn làm với cái cũ Http. HTTP_INTERCEPTORSThay vào đó, bạn có thể cung cấp một triển khai có thể là một mảng với 'multi: true'tùy chọn:

import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
...

@NgModule({
  ...
  imports: [
    ... ,
    HttpClientModule
  ],
  providers: [
    ... ,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorOne,
      multi: true,
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: InterceptorTwo,
      multi: true,
    }
  ],
  ...
})

Đánh chặn:

import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
...

@Injectable()
export class InterceptorOne implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('InterceptorOne is working');
    return next.handle(req);
  }
}

@Injectable()
export class InterceptorTwo implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('InterceptorTwo is working');
    return next.handle(req);
  }
}

Cuộc gọi máy chủ này sẽ in cả hai thông báo nhật ký của bộ đánh chặn:

import {HttpClient} from '@angular/common/http';
...

@Component({ ... })
export class SomeComponent implements OnInit {

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.http.get('http://some_url').subscribe();
  }
}

4
Có cách nào để cho biết apicuộc gọi chỉ có thể bị chặn bởi một interceptor? hoặc bằng bất kỳ điều kiện nào?
k11k2

@ k11k2 và cho mọi người đang tìm kiếm, đây là câu hỏi và câu trả lời về điều này: stackoverflow.com/questions/45781379/… Tôi thừa nhận rằng tôi vẫn còn một chút bối rối về nó.
trollkotze

Tại sao phải là @Injectable ()? Nó hoạt động mà không cần @Injectable () cho tôi
makkasi

1
@makkasi: Cần thêm @ Injectable nếu lớp đánh chặn cần thực hiện bất kỳ quá trình tiêm phụ thuộc nào của riêng nó. Trong ví dụ được đưa ra, nó không phải là cần thiết
jintoppy

Làm thế nào để khắc phục về thứ tự đánh chặn?
AmirReza-Farahlagha
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.