Angular 6将Http Interceptor与配置服务一起使用 [英] Angular 6 use Http Interceptor with config service
问题描述
我正在使用Angular 6,问题是当我尝试将拦截器与APP_INITIALIZER一起用作应用程序模块提供程序以从本地获取json配置文件时。
I'm using Angular 6 and the issue is when I try to use an interceptor as an app module provider together with the APP_INITIALIZER to get the json config file from local.
我的应用模块片段是:
../ src / app / app.module.ts(提供者片段)
../src/app/app.module.ts (the providers fragment)
providers: [
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: initializeApp,
deps: [AppConfigService], multi: true
},
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
{ provide: LOCALE_ID, useValue: 'ES' },
Title,
]
有趣的是,如果我删除了拦截器,代码就会起作用以及带来的配置文件。我获取配置文件的代码是:
It's interesting that if I remove the interceptors, the code works well bringing the config file. My code to get the config file is:
../ src / app / _services / app-config.service.ts
../src/app/_services/app-config.service.ts
import { Injectable } from '@angular/core';
import { Response } from '@angular/http';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment.dev';
import { IAppConfig } from '../_models/_interfaces/app-config.model';
@Injectable()
export class AppConfigService {
static settings: IAppConfig;
constructor(private http: HttpClient) {}
load() {
const jsonFile = `../../assets/config/config.${environment.name}.json`;
return new Promise<void>((resolve, reject) => {
this.http.get(jsonFile).toPromise().then((response: Response) => {
AppConfigService.settings = <IAppConfig>response;
resolve();
}).catch((response: any) => {
reject(`Could not load file '${jsonFile}': ${JSON.stringify(response)}`);
});
});
}
}
最后,拦截器代码:
../ src / app / _interceptors / token.interceptor.ts
../src/app/_interceptors/token.interceptor.ts
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { AuthService } from '../_services/auth.service';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(public auth: AuthService) {}
intercept(request: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.auth.getToken()}`
}
});
return next.handle(request);
}
}
当Angular编译应用程序时,它将返回:
When Angular compile the app it returns:
无法加载文件'../../assets/config/config.dev.json':{}
Could not load file '../../assets/config/config.dev.json': {}
我尝试了几种方法来避免此问题,但直到现在仍无法解决。
I've tried several approaches trying to avoid this issue, but can't solve it until now.
有什么建议吗?
预先感谢。
推荐答案
在使用HttpClient获取配置文件时,拦截器也会过滤该请求。在您的代码中,拦截器正在用Authorization标头替换(不附加到现有的)所有HTTP标头。当默认的Content-Type application / json丢失时,该请求将不再起作用。在将旧标头设置为克隆的标头之前,请使用request.headers.append(...)保存并修改旧标头。
When you are using HttpClient to get your configuration file, your interceptor is filtering that request as well. In your code the interceptor is replacing (not appending to existing) all the HTTP headers with Authorization header. When the default Content-Type application/json is lost, the request doesn't work anymore. Save and modify the old headers with request.headers.append(...) before setting them to cloned one.
OR
在拦截器中为文件请求定义一个异常。一种简单的方法是检查request.url中使用的URL
Define an exception for your file request in the interceptor. One simple way is to check which URL is used in request.url
if (request.url.indexOf('config') > -1) {
requestModified = request.clone({
url: request.url,
headers: request.headers.set('Content-Type', 'application/json')
});
}
这篇关于Angular 6将Http Interceptor与配置服务一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!