코어 모듈에 추가된 http 인터셉터를 무시하도록 앵글 모듈을 만드는 방법
권한 부여 처리를 위해 HttpInterceptor가 포함된 코어 모듈이 있으며 이 모듈을 AppModule에 포함합니다. 이 방식으로 HttpClient를 사용하는 다른 모든 모듈이 이 인터셉터를 사용합니다.
@NgModule({
imports: [],
declarations: [],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
},
]
})
export class CoreModule { }
모듈을 기본 인터셉터로 우회시키는 방법은 무엇입니까?
@NgModule({
imports: [
CommonModule
],
declarations: components,
providers: [CustomService],
exports: components,
})
export class ModuleWithoutInterceptorModule { }
HttpBackend를 사용할 수 있습니다.
예:
import { HttpClient, ..., HttpBackend } from '@angular/common/http';
@Injectable()
export class TestService {
private httpClient: HttpClient;
constructor( handler: HttpBackend) {
this.httpClient = new HttpClient(handler);
}
이러한 방식으로 AuthInterceptor는 서비스를 가로채지 않습니다.
GitHub에 대한 이 제안에 따라, 우리는 가로채서는 안 되는 요청을 식별하기 위해 간단한 헤더를 구현했습니다.인터셉트에서:
export const InterceptorSkipHeader = 'X-Skip-Interceptor';
@Injectable()
export class SkippableInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.headers.has(InterceptorSkipHeader)) {
const headers = req.headers.delete(InterceptorSkipHeader);
return next.handle(req.clone({ headers }));
}
... // intercept
}
}
그런 다음 특정 요청에 대한 가로채기를 건너뛸 때마다 다음을 수행합니다.
const headers = new HttpHeaders().set(InterceptorSkipHeader, '');
this.httpClient
.get<ResponseType>(someUrl, { headers })
...
이 방법을 사용하면 인터셉터가 아닌 서비스가 인터셉터의 로직이 적용되는 시기를 선택합니다. 즉, 서비스는 응용 프로그램의 인터셉터에 대해 "알고 있어야" 합니다.사용 사례에 따라 인터셉터가 로직을 적용할 시기를 결정하도록 하는 것이 더 나을 수 있습니다.
모든 인터셉트를 우회하기 위해 @deg 제안대로 HttpBackend를 사용할 수 있습니다.
다른 경우에는 인터셉터 체인에서 인터셉터를 제외할 수 있는 HttpClient 팩토리를 만들 수 있습니다.
import { createHttpClient } from './http-client.factory';
// ...
@Injectable({
providedIn: 'root'
})
export class TodosApiService {
http = createHttpClient(this.injector, [Interceptor2]);
// ^^^^^^^^^^^^
// Interceptors to exclude
constructor(private injector: Injector) { }
getTodo() {
// Interceptor2 will be bypassed
return this.http.get('https://jsonplaceholder.typicode.com/todos')
}
}
기본 클래스를 만들어 이 논리를 재사용할 수 있습니다.
@Injectable()
export class BasicHttpClient {
protected http = createHttpClient(this.injector, [Interceptor2]);
constructor(private injector: Injector) { }
}
@Injectable({ providedIn: 'root' })
export class TodosApiService extends BaseHttpClient {
getTodo() {
// Interceptor2 will be bypassed
return this.http.get('https://jsonplaceholder.typicode.com/todos')
}
}
http-client.factory.ts
import {
HTTP_INTERCEPTORS,
HttpBackend,
HttpClient,
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { Injector, Type } from '@angular/core';
class HttpInterceptorHandler implements HttpHandler {
constructor(private next: HttpHandler, private interceptor: HttpInterceptor) {}
handle(req: HttpRequest<any>): Observable<HttpEvent<any>> {
return this.interceptor.intercept(req, this.next);
}
}
class HttpInterceptingHandler implements HttpHandler {
private chain: HttpHandler | null = null;
constructor(
private backend: HttpBackend,
private injector: Injector,
private interceptorsToExclude: Type<HttpInterceptor>[],
private intercept?: (req: HttpRequest<any>) => HttpRequest<any>
) {}
handle(req: HttpRequest<any>): Observable<HttpEvent<any>> {
if (this.intercept) {
req = this.intercept(req);
}
if (this.chain === null) {
const interceptors = this.injector
.get(HTTP_INTERCEPTORS, [])
.filter(
interceptor => !this.interceptorsToExclude.some(interceptorType => interceptor instanceof interceptorType)
);
this.chain = interceptors.reduceRight(
(next, interceptor) => new HttpInterceptorHandler(next, interceptor),
this.backend
);
}
return this.chain.handle(req);
}
}
export function createHttpClient(
injector: Injector,
excludedInterceptors: Type<HttpInterceptor>[],
intercept?: (req: HttpRequest<any>) => HttpRequest<any>
) {
return new HttpClient(
new HttpInterceptingHandler(injector.get(HttpBackend), injector, excludedInterceptors, intercept)
);
}
Angular 12에서, 이것은 다음과 같이 달성될 수 있습니다.HttpContext
의 재산.HttpRequest
!
이 방법은 헤더 제거를 위한 논리가 필요하지 않으며 요청별로 수행할 수 있기 때문에 좋습니다.
export const DISABLE_GLOBAL_EXCEPTION_HANDLING = new HttpContextToken<boolean>(() => false);
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.ignoreErrorHandling(request)) {
return next.handle(request);
}
return next.handle(request).pipe(
catchError((error) => {
// normal intercepting logic
return throwError(() => error);
}),
);
private ignoreErrorHandling(request: HttpRequest<any>) {
return request.context.get(DISABLE_GLOBAL_EXCEPTION_HANDLING);
}
토큰을 추가하여 개별 요청을 비활성화할 수 있습니다.
this.httpClient.get<ResponseType>(`/api`, {
context: new HttpContext().set(DISABLE_GLOBAL_EXCEPTION_HANDLING, true),
});
언급URL : https://stackoverflow.com/questions/46469349/how-to-make-an-angular-module-to-ignore-http-interceptor-added-in-a-core-module
'source' 카테고리의 다른 글
PHP의 base64 문자열에서 이미지 유형 탐지 (0) | 2023.08.08 |
---|---|
테이블스페이스 'USERS'에 대한 권한 없음 (0) | 2023.08.08 |
모듈에서 사용 가능한 명령을 검색하려면 어떻게 해야 합니까? (0) | 2023.07.29 |
분할 오류와 스택 오버플로의 차이점은 무엇입니까? (0) | 2023.07.29 |
여러 열이 있는 인덱스 - 하나의 열에 대해서만 쿼리를 수행할 때 확인하시겠습니까? (0) | 2023.07.29 |