目的: 要发送带有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
答案 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)
问题出在后端部分,适用标题的设置受到限制。