我正在使用HTTP拦截器以便向请求添加身份验证令牌,但是当http客户端触发请求时,该请求将被拦截并发送两次
这是我的HttpClient呼叫
searchProd(query: string, limit?: number): Observable<Product[]> {
let _limit = limit || 5;
return this.http.get<Product[]>(`${API_CONST.HOST}/${API_CONST.PRODUCT}?search=${query}&limit=${_limit}`);
}
这是我的app.module.ts
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptor } from './auth/token.interceptor';
....
@NgModule({
declarations: [
...
],
imports: [
...
],
providers: [
ApiService,
AuthGuardService,
SettingsService,
{
provide : HTTP_INTERCEPTORS,
useClass : TokenInterceptor,
multi : true
}
],
entryComponents: [ ... ],
bootstrap: [ ... ]
})
这是我的token.interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse,
HttpErrorResponse
} from '@angular/common/http';
import { AngularFireAuth } from '@angular/fire/auth';
import { Observable } from 'rxjs';
import { AuthGuardService } from './auth-guard.service';
import { API_CONST } from '../services/api/api.service';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
private no_auth_endpoints = [
`${API_CONST.HOST}/${API_CONST.PRODUCT}`
]
private token = null;
constructor(public af: AngularFireAuth, private authGuard: AuthGuardService) {
this.token = authGuard.getToken();
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headersConfig = {
'Authorization': `Bearer ${this.token}`
};
let isAuthEnpoint = true;
this.no_auth_endpoints.forEach(endpoint => {
if(request.url.includes(endpoint))
isAuthEnpoint = false;
})
if (!request.headers.has('Authorization') && isAuthEnpoint) {
const modified = request.clone({
setHeaders : headersConfig
});
return next.handle(modified); //this line is executed twice!
}
else {
return next.handle(request); //this line is executed twice!
}
}
}
通过chrome开发工具,我在“网络”标签中看到了两次发送的相同请求。在调试期间,我看到searchProd发送了一次HTTP请求,但是当接收到该请求时,next.handle()被执行了两次。如何解决该问题,以便仅发送一个请求?
编辑:这是“网络”标签中显示的内容
EDIT2:这是我调用searchProd(string)函数的代码。
component.html
<mat-form-field class="bottom-search-field">
<input [formControl]="autoCompleteControl" type="text" placeholder="Aggiungi un prodotto"
matInput [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="onSelectionChanged($event)">
<mat-option *ngFor="let item of searchResults | async; let index = index" [value]="item.description | titlecase">
{{ item.description | titlecase}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
component.ts
public autoCompleteControl = new FormControl();
...
ngOnInit(): void {
this.searchResults = this.autoCompleteControl.valueChanges.pipe(
startWith(''),
switchMap(value => {
if (value.length > 3) {
let prodSearched = this.apiService.searchProd(value);
prodSearched.pipe(share()); // ADDED PIPE SHARE
this.saveProdSearched(prodSearched);
return prodSearched;
} else {
return of(null);
}
})
);
}
//This function save the last result inside of an array of Product
private saveProdSearched(prodSearched: Observable<Product[]>) {
prodSearched.subscribe(items => {
this.lastSearch = items
})
}
答案 0 :(得分:0)
问题是我订阅了两次。一个在函数this.saveProdSearched(prodSearched);
中,另一个在带有管道async
的模板中。我解决了这个问题,只需保存saveProdSearched()
函数的结果,从模板中删除异步管道,并显示Product数组中的结果