diff --git a/docs/en/UI/Angular/HTTP-Requests.md b/docs/en/UI/Angular/HTTP-Requests.md index 57a058ef36..a0e53df9c9 100644 --- a/docs/en/UI/Angular/HTTP-Requests.md +++ b/docs/en/UI/Angular/HTTP-Requests.md @@ -298,3 +298,15 @@ export function handleHttpErrors(injector: Injector, httpError: HttpErrorRespons return throwError(httpError) } ``` + + +### How to Skip HTTP interceptors and ABP headers + +The ABP Framework adds several HTTP headers to the HttpClient, such as the "Auth token" or "tenant Id". +The ABP Server must possess the information but the ABP user may not want to send this informations to an external server. +ExternalHttpClient and IS EXTERNAL REQUEST HttpContext Token were added in V6.0.4. +The ABP Http interceptors check the value of the `IS_EXTERNAL_REQUEST` token. If the token is True then ABP-specific headers won't be added to Http Request. +The `ExternalHttpClient` extends from `HTTPClient` and sets the `IS_EXTERNAL_REQUEST` context token to true. +When you are using `ExternalHttpClient` as HttpClient in your components, it does not add ABP-specific headers. + +Note: With `IS_EXTERNAL_REQUEST` or without it, ABP loading service works. diff --git a/npm/ng-packs/packages/core/src/lib/clients/http.client.ts b/npm/ng-packs/packages/core/src/lib/clients/http.client.ts new file mode 100644 index 0000000000..c6e9017be7 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/clients/http.client.ts @@ -0,0 +1,30 @@ +import { HttpClient, HttpContext, HttpRequest } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { IS_EXTERNAL_REQUEST } from '../tokens/http-context.token'; + +// source : https://github.com/armanozak/demo-angular-server-specific-interceptors +@Injectable({ + providedIn: 'root', +}) +export class ExternalHttpClient extends HttpClient { + override request( + first: string | HttpRequest, + url?: string, + options: RequestOptions = {}, + ): Observable { + if (typeof first === 'string') { + this.#setPlaceholderContext(options); + return super.request(first, url, options); + } + + this.#setPlaceholderContext(first); + return super.request(first); + } + #setPlaceholderContext(optionsOrRequest: { context?: HttpContext }) { + optionsOrRequest.context ??= new HttpContext(); + optionsOrRequest.context.set(IS_EXTERNAL_REQUEST, true); + } +} + +type RequestOptions = Parameters[2]; diff --git a/npm/ng-packs/packages/core/src/lib/clients/index.ts b/npm/ng-packs/packages/core/src/lib/clients/index.ts new file mode 100644 index 0000000000..c9aba4d030 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/clients/index.ts @@ -0,0 +1 @@ +export * from './http.client'; diff --git a/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts b/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts index d3dbe19ec0..e09bb6292e 100644 --- a/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts +++ b/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts @@ -5,6 +5,7 @@ import { finalize } from 'rxjs/operators'; import { SessionStateService } from '../services/session-state.service'; import { HttpWaitService } from '../services/http-wait.service'; import { TENANT_KEY } from '../tokens/tenant-key.token'; +import { IS_EXTERNAL_REQUEST } from '../tokens/http-context.token'; @Injectable({ providedIn: 'root', @@ -19,12 +20,14 @@ export class ApiInterceptor implements HttpInterceptor { intercept(request: HttpRequest, next: HttpHandler) { this.httpWaitService.addRequest(request); - return next - .handle( - request.clone({ + const isExternalRequest = request.context?.get(IS_EXTERNAL_REQUEST); + const newRequest = isExternalRequest + ? request + : request.clone({ setHeaders: this.getAdditionalHeaders(request.headers), - }), - ) + }); + return next + .handle(newRequest) .pipe(finalize(() => this.httpWaitService.deleteRequest(request))); } diff --git a/npm/ng-packs/packages/core/src/lib/tokens/http-context.token.ts b/npm/ng-packs/packages/core/src/lib/tokens/http-context.token.ts new file mode 100644 index 0000000000..e935232b08 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tokens/http-context.token.ts @@ -0,0 +1,3 @@ +import { HttpContextToken } from '@angular/common/http'; + +export const IS_EXTERNAL_REQUEST = new HttpContextToken(() => false); diff --git a/npm/ng-packs/packages/core/src/lib/tokens/index.ts b/npm/ng-packs/packages/core/src/lib/tokens/index.ts index 98985107f3..e0116e007a 100644 --- a/npm/ng-packs/packages/core/src/lib/tokens/index.ts +++ b/npm/ng-packs/packages/core/src/lib/tokens/index.ts @@ -7,3 +7,4 @@ export * from './manage-profile.token'; export * from './options.token'; export * from './queue.token'; export * from './tenant-key.token'; +export * from './http-context.token'; diff --git a/npm/ng-packs/packages/core/src/public-api.ts b/npm/ng-packs/packages/core/src/public-api.ts index a5cbd78e4e..e740b4c4df 100644 --- a/npm/ng-packs/packages/core/src/public-api.ts +++ b/npm/ng-packs/packages/core/src/public-api.ts @@ -23,3 +23,4 @@ export * from './lib/strategies'; export * from './lib/tokens'; export * from './lib/utils'; export * from './lib/validators'; +export * from './lib/clients';