angular - Problema al configurar el encabezado usando HttpInterceptor
Tengo el siguiente código:
// config.service.ts
import { Injectable } from "@angular/core";
@Injectable()
export class ConfigService {
private language: string = "en";
constructor() {}
set Language(lang: string) {
this.language = lang;
}
get Language(): string {
return this.language;
}
}
// app.module.ts
import { BrowserModule } from "@angular/platform-browser";
import { NgModule, APP_INITIALIZER } from "@angular/core";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { AnalyticsService, CoreModule, CrossDomainService } from "./core";
import { TileModule } from "./tile/tile.module";
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, TileModule, CoreModule.forRoot()],
providers: [
{
provide: APP_INITIALIZER,
useFactory: onModuleInit,
multi: true,
deps: [CrossDomainService, AnalyticsService]
}
],
bootstrap: [AppComponent]
})
export class AppModule {}
export function onModuleInit(
crossDomainService: CrossDomainService,
analyticsService: AnalyticsService
) {
return () => {
console.log("App Init");
crossDomainService.init();
analyticsService.init();
return new Promise(resolve => resolve(true));
};
}
//core.module.ts
import { NgModule, ModuleWithProviders } from "@angular/core";
import { CommonModule } from "@angular/common";
import {
HTTP_INTERCEPTORS,
HttpClientModule,
HttpClient
} from "@angular/common/http";
import { HttpRequestInterceptor } from "./http-request.interceptor";
import { ArticleService } from "./article.service";
import { CrossDomainService } from "./cross-domain.service";
import { AnalyticsService } from "./analytics.service";
import { TranslateModule, TranslateLoader } from "@ngx-translate/core";
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
import { ConfigService } from "../config.service";
export function translateHttpLoaderFactory(http: HttpClient) {
//return new TranslateHttpLoader(http);
return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
}
@NgModule({
imports: [
CommonModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translateHttpLoaderFactory,
deps: [HttpClient]
}
})
],
providers: [
ArticleService,
CrossDomainService,
AnalyticsService,
{
provide: HTTP_INTERCEPTORS,
useClass: HttpRequestInterceptor,
multi: true
}
]
})
export class CoreModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: CoreModule,
providers: [ConfigService]
};
}
}
//http-request.interceptor.ts
import { Injectable } from "@angular/core";
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from "@angular/common/http";
import { Observable } from "rxjs/Observable";
import { ConfigService } from "../config.service";
@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {
language: string = "en";
constructor(private config: ConfigService) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const request = req.clone({
setHeaders: { "Accept-Language": this.config.Language }
});
console.log(
`Request header value : ${request.headers.get("Accept-Language")}`
);
return next.handle(request);
}
}
CrossDomainService, en este caso se utiliza para obtener el idioma de un sistema externo. Es un conector entre la aplicación y los servicios externos.
El marco externo en este ejemplo va a suministrar el idioma a la aplicación Sample Angular. Supongamos que el valor inicial del idioma es 'en' y ahora si lo actualizamos a 'es', veo que HttpRequestInterceptor primero selecciona 'en' y luego 'es'. Entonces, todas las solicitudes de la API toman el valor del encabezado 'Accept-Language' como 'en' en lugar de 'es'. Si el marco externo está enviando el idioma 'fr', entonces en este caso veo que HttpRequestInterceptor primero selecciona 'es' y luego 'fr'. Por lo tanto, habrá algunas solicitudes de API que toman el valor del encabezado 'Accept-Language' como 'es' en lugar de 'fr'.
¿Alguien puede ayudarme a saber cómo solucionar este problema?
Respuesta #1
intenta reemplazar setheaders con headers así.
const request = req.clone({headers: req.headers.set('Accept-Language',this.config.Language)});
Respuesta #2
Sé que esta es una pregunta antigua, pero en caso de que alguien tenga problemas para configurar el encabezado 'Accept-Language' en todas las solicitudes en un interceptor, use esto:
request = request.clone({
setHeaders: {
'Accept-Language': this.config.Language + ';q=0.9,en-US,en;q=0.8'
}
});
Esto funciona en Angular 11.2.
