角度6,无法应用多个HttpHeaders

时间:2018-08-08 15:00:13

标签: angular http-headers angular6

目的: 要发送带有2个默认标头的请求:内容类型和授权(后端-Web API)。 条件: Angular版本6.0.1和使用生成器ngx-rocket构建的项目。 问题: 我为Content-Type添加了拦截器,它可以正常工作。

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      url: environment.serverUrl + request.url,
      setHeaders: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: this.convertToContentType(request.body)
    });
    return next.handle(request);
  }

当我尝试在同一函数中添加另一个标头时,没有人应用标头,并且在每种情况下都存在相同的情况。它仅适用于一个标头。我试图添加另一个拦截器

@Injectable()
export class AuthorizationInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const credentialsData = localStorage.getItem(token_key);
    if (credentialsData && JSON.parse(credentialsData)) {
      request = request.clone({
        // headers: new HttpHeaders().set('Authorization', `Bearer ${JSON.parse(credentialsData).token}`)
        setHeaders: {
          'Authorization': `Bearer ${JSON.parse(credentialsData).token}`
        }
      });
    }
    return next.handle(request);
  }

}

这是我的http.service.ts服务代码

import {Inject, Injectable, InjectionToken, Injector, Optional} from '@angular/core';
import {HttpClient, HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs';

import {ErrorHandlerInterceptor} from './error-handler.interceptor';
import {CacheInterceptor} from './cache.interceptor';
import {ApiPrefixInterceptor} from './api-prefix.interceptor';
import {AuthorizationInterceptor} from '@app/core/http/api-prefix.interceptor';

// HttpClient is declared in a re-exported module, so we have to extend the original module to make it work properly
// (see https://github.com/Microsoft/TypeScript/issues/13897)
declare module '@angular/common/http/src/client' {

  // Augment HttpClient with the added configuration methods from HttpService, to allow in-place replacement of
  // HttpClient with HttpService using dependency injection
  export interface HttpClient {

    /**
     * Enables caching for this request.
     * @param {boolean} forceUpdate Forces request to be made and updates cache entry.
     * @return {HttpClient} The new instance.
     */
    cache(forceUpdate?: boolean): HttpClient;

    /**
     * Skips default error handler for this request.
     * @return {HttpClient} The new instance.
     */
    skipErrorHandler(): HttpClient;

    /**
     * Do not use API prefix for this request.
     * @return {HttpClient} The new instance.
     */
    disableApiPrefix(): HttpClient;

    disableAuthorizationHeader(): HttpClient;

  }

}

// From @angular/common/http/src/interceptor: allows to chain interceptors
class HttpInterceptorHandler implements HttpHandler {

  constructor(private next: HttpHandler, private interceptor: HttpInterceptor) {
  }

  handle(request: HttpRequest<any>): Observable<HttpEvent<any>> {
    return this.interceptor.intercept(request, this.next);
  }

}

/**
 * Allows to override default dynamic interceptors that can be disabled with the HttpService extension.
 * Except for very specific needs, you should better configure these interceptors directly in the constructor below
 * for better readability.
 *
 * For static interceptors that should always be enabled (like ApiPrefixInterceptor), use the standard
 * HTTP_INTERCEPTORS token.
 */
export const HTTP_DYNAMIC_INTERCEPTORS = new InjectionToken<HttpInterceptor>('HTTP_DYNAMIC_INTERCEPTORS');

/**
 * Extends HttpClient with per request configuration using dynamic interceptors.
 */
@Injectable()
export class HttpService extends HttpClient {

  constructor(private httpHandler: HttpHandler,
              private injector: Injector,
              @Optional() @Inject(HTTP_DYNAMIC_INTERCEPTORS) private interceptors: HttpInterceptor[] = []) {
    super(httpHandler);

    if (!this.interceptors) {
      // Configure default interceptors that can be disabled here
      this.interceptors = [
        this.injector.get(ApiPrefixInterceptor),
        // this.injector.get(AuthorizationInterceptor),
        this.injector.get(ErrorHandlerInterceptor)
      ];
    }
  }

  cache(forceUpdate?: boolean): HttpClient {
    const cacheInterceptor = this.injector.get(CacheInterceptor).configure({update: forceUpdate});
    return this.addInterceptor(cacheInterceptor);
  }

  skipErrorHandler(): HttpClient {
    return this.removeInterceptor(ErrorHandlerInterceptor);
  }

  disableApiPrefix(): HttpClient {
    return this.removeInterceptor(ApiPrefixInterceptor);
  }

  disableAuthorizationHeader(): HttpClient {
    return this.removeInterceptor(AuthorizationInterceptor);
  }

  // Override the original method to wire interceptors when triggering the request.
  request(method?: any, url?: any, options?: any): any {
    const handler = this.interceptors.reduceRight(
      (next, interceptor) => {
        return new HttpInterceptorHandler(next, interceptor);
      }, this.httpHandler
    );
    return new HttpClient(handler).request(method, url, options);
  }

  private removeInterceptor(interceptorType: Function): HttpService {
    return new HttpService(
      this.httpHandler,
      this.injector,
      this.interceptors.filter(i => !(i instanceof interceptorType))
    );
  }

  private addInterceptor(interceptor: HttpInterceptor): HttpService {
    return new HttpService(
      this.httpHandler,
      this.injector,
      this.interceptors.concat([interceptor])
    );
  }

}

我已经确定问题出在头文件上,而不是拦截器机制上。

更新

这是“请求网络”标签的屏幕截图,以确保标头丢失。 Network screenshot

2 个答案:

答案 0 :(得分:0)

您是否尝试过此代码

let headers = request.headers
        .set('Content-Type', 'application/json')
        .set('Authorization', `Bearer ${JSON.parse(credentialsData).token}`);

@Injectable()
export class AuthorizationInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const credentialsData = localStorage.getItem(token_key);
    if (credentialsData && JSON.parse(credentialsData)) {
      request = request.clone({ headers });
    }
    return next.handle(request);
  }

}

答案 1 :(得分:0)

问题出在后端部分,适用标题的设置受到限制。