Angular 6将Http Interceptor与配置服务一起使用 [英] Angular 6 use Http Interceptor with config service

查看:167
本文介绍了Angular 6将Http Interceptor与配置服务一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆