angular - HTTP拦截器发送相同的请求两次

标签 angular rxjs angular-httpclient angular-http-interceptors

我正在使用 HTTP 拦截器来向请求添加身份验证 token ,但是当 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() 被执行两次。如何解决这个问题以便只发送一个请求?

编辑:这是网络选项卡中显示的内容

第一个请求
Request 1

第二个请求
Request 2

EDIT2:这是我调用 searchProd(string) 函数的代码。

组件.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>

组件.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
    })
  }

最佳答案

问题是我订阅了两次。功能之一this.saveProdSearched(prodSearched);和一个在模板与管道 async .我解决了这个问题,只需保存 saveProdSearched() 的结果函数,从模板中移除异步管道并显示来自 Product 数组的结果

关于angular - HTTP拦截器发送相同的请求两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55982043/

相关文章:

angular - 将数据从服务传递到组件 --> 子组件

node.js - 安装node-sass文件后出现错误

javascript - Angular 的链接函数与 Angular 2 的构造函数

javascript - Angular 2 json获取数据对象

css - 更改内部类样式以溢出 : visible for specific class (For PrimeNG)

angular - 使用 typescript ,什么是最好的 Observable 类型来最好地表示没有内容的 HTTP 响应?

javascript - 使用 ngrx/store 进行观察 - 竞争条件

javascript - GHCJS:如何使用 FFI 导入高阶 javascript 函数?

java - 如何在 Spring Security 后端从 Angular 应用程序正确验证用户身份

angular - 如何在Angular 8中显示超时错误