Http-запрос отправляется несколько раз в приложении Angular 6 - PullRequest
0 голосов
/ 01 ноября 2018

В нашем приложении angular 6 я заметил, что некоторые вызовы Http GET выполняются как минимум два раза. Иногда OPTIONS и / или первый GET отменяется, и только второй вызов завершается успешно. В других случаях один и тот же вызов GET выполняется два или более раз.

enter image description here

Компонент нижнего колонтитула вызывает службу для получения текущей версии приложения и отображения ее шаблона. Простой Observable с подпиской, без какого-либо специального оператора.

UPDATE
После дальнейшего исследования проблема, похоже, связана с combineLatest в HttpInterceptor. Поскольку две наблюдаемые испускаются как наблюдаемые объектом BehaviourSubject (каждый), я полагаю разную скорость / время, когда эти субъекты излучают, сделайте так, чтобы combatels запускался дважды или более.

Служба имитатора (испускает наблюдаемые из объекта поведения)

export class ImpersonatorService {
public get changeHandler(): Observable<string> {
    return this.changeHandlerInternal.asObservable();
}

private changeHandlerInternal = new BehaviorSubject<string>(this.get());
private key = "impersonate";
constructor(private cookieService: CookieService) {}

public set(impersonate: string) {
    this.cookieService.put(this.key, impersonate);
    this.changeHandlerInternal.next(impersonate);
}

private get(): string {
    let impersonate = this.cookieService.get(this.key);
    if (impersonate === undefined || impersonate === null || impersonate === "") {
        impersonate = "";
    }

    return impersonate;
}
}

Нижний колонтитул :

export class FooterComponent implements OnInit {
public applicationInfo: Observable<ApplicationInfo>;

constructor(private applicationService: ApplicationInfoService) {}

ngOnInit() {
    this.applicationInfo = applicationService.getApplicationInfo();
  }
}

Шаблон нижнего колонтитула

<div>
    {{ (applicationInfo | async)?.version }}
</div>

Служба подачи заявок

export class ApplicationInfoService {
constructor(private http: HttpClient, @Inject(APP_CONFIG) private config: IAppConfig) {}

public getApplicationInfo(): Observable<ApplicationInfo> {
    return this.http.get<ApplicationInfo>(this.config.apiEndpoint + "/api/applicationinfo");
   }
}

Служба приложения вызывается только из компонента нижнего колонтитула.

Мы также используем HttpInterceptor для внедрения заголовков:

export class HttpInterceptor implements HttpInterceptor {
constructor(private impersonator: ImpersonatorService, private profileService: ProfileService, private languageService: TranslateService) {}

public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.impersonator.changeHandler
        .combineLatest(this.profileService.changeHandler, (user, profile) => {
            let customHeaders = req.headers.set("X-Impersonate", user).set("X-Profile", profile);

            if (customHeaders.has("Content-Type")) {
                if (customHeaders.get("Content-Type") === "multipart/form-data") {
                    customHeaders = customHeaders.delete("Content-Type");
                }
            } else {
                customHeaders = customHeaders.set("Content-Type", "application/json");
            }

            const clonedReq = req.clone({ headers: customHeaders, withCredentials: true });
            return next.handle(clonedReq);
        })
        .switch();
    }
}

Чтение из других ответов SO, похоже, связано с расой. Однако в других обнаруженных случаях использовались switchMap или другие операторы, вызывающие проблемы в этих сценариях.

При отладке я вижу, что внутри HttpInterceptor поступают два запроса на конечную точку ApplicationInfo. Но как я могу гарантировать, что запросы на дубликаты не будут отправлены?

...