Angular 6,不能应用多个HttpHeaders
Posted
技术标签:
【中文标题】Angular 6,不能应用多个HttpHeaders【英文标题】:Angular 6, multiple HttpHeaders can't be applied 【发布时间】:2019-01-15 21:46:46 【问题描述】:目的: 使用 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
【问题讨论】:
您是否将授权标头暴露到您的后端? 看看这个***.com/questions/50968674/… @firegloves 我认为如果我发送标头,它们将在网络选项卡中可见。我看不到他们。我错了吗? 别想:试试 :) 我在开玩笑,我不记得你是否可以在网络选项卡中看到,也许不是 请记住,浏览器可以知道该特定标头是否有效,因为您已经与服务器进行了数据交换 【参考方案1】:你试过这个代码吗
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);
【讨论】:
很遗憾,是的【参考方案2】:问题出在后端部分,可应用的标头有设置限制。
【讨论】:
以上是关于Angular 6,不能应用多个HttpHeaders的主要内容,如果未能解决你的问题,请参考以下文章