Не удалось перехватить код состояния 401 в HTTP-перехватчике Angular 7

#javascript #angular #http

#javascript #angular #http

Вопрос:

Я использую Angular 7, и я использовал HTTP-перехватчик в своем приложении.

Я не могу отследить код состояния 401 в этом HTTP-перехватчике.

Я попытался сделать точечную разметку catchError и tap , но он выдает статус 0, я хочу 401.

Мой код здесь:

 return next.handle(request).pipe(tap(event => {
            console.log('the ev is :', event);
            if (event instanceof HttpResponse) {
                this.onEnd();
            }
         }, err => {
            if (err instanceof HttpErrorResponse) {
                console.log('the eeeeeee is :', err);
                this.onEnd();
                // User logged out
                if (err.status === 401) {
                    this.router.navigate(['logout']);
                }
            }
        })).pipe(catchError(error => {
            console.log('the ee is :', error);
            return Observable.throw(error);
        }));
  

Спасибо.

Комментарии:

1. Я не уверен, что tap срабатывает при возникновении ошибки. Погуглите для этого.

2. я сталкиваюсь с этой проблемой, и причина была только в режиме разработки, я получал статус 0, в то время как в сервисе я получал 401, а в перехватчике я получал 0. при развертывании приложения на сервере. все работало нормально, и я получил правильные статусы без каких-либо изменений в коде или конфигурации. я не знаю почему, но это происходило только в режиме разработки.

3. @FarhatZaman, Даже после развертывания приложения на сервере существует та же проблема.

Ответ №1:

У вас есть обработчик ошибок в tap методе, а затем отдельный конвейер catchError . Если только вы не собираетесь действовать в соответствии с полученным ответом, то есть http 200. Простая реализация перехватчика была бы:

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

  return next.handle(request).pipe(
      catchError(err => {
        if (err instanceof HttpErrorResponse) {

          if (err.status === 401 || err.status === 403) {
              // Invalidate user session and redirect to login/home
          }

          // return the error back to the caller
          return throwError(err);
        }
      }),
      finalize(() => {
        // any cleanup or final activities
      })
    );
}
  

Ответ №2:

Я использую angular 6, и это перенаправляет на страницу входа в систему при возникновении ошибки 401 или 403. Я думаю, что это должно работать в angular 7. Должны быть другие способы сделать это, но я делюсь тем, что работает для меня в этом случае. Надеюсь, это поможет.

 intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
      catchError(
        err =>
          new Observable<HttpEvent<any>>(observer => {
            if (err instanceof HttpErrorResponse) {
              const errResp = <HttpErrorResponse>err;
              if (errResp.status === UNAUTHORIZED || err.status === FORBIDDEN) {
                this.authService.goToLogin(this.router.url);
              }
            }
            observer.error(err);
            observer.complete();
          })
      )
    );
  

}

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

Комментарии:

1. Нет необходимости создавать новый Observable в обработчике ошибок и вызывать observer.error(err) снова. Вы можете просто вернуть ошибку, которая продолжит наблюдаемое с ошибкой фактическому вызывающему. Я опубликовал пример ниже.

2. @dcg все еще 0 входит errResp.status .

3. @ArpitMeena Вы уверены, что попали на сервер?

Ответ №3:

 import { Injectable } from '@angular/core'
import { HttpEvent, HttpRequest, HttpHandler, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'
import { Router } from '@angular/router'
import { Observable, of } from 'rxjs'
import { catchError } from 'rxjs/operators'

@Injectable()
export class ServerErrorInterceptor implements HttpInterceptor {
  constructor(public router: Router) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error: any) => {
        if (error.status == 401 || error.status == 0) {
          this.router.navigate(['/'])
        } else {
        }
        return of(error)
      }),
    )
  }
}
  
 providers: [
  {
    provide: HTTP_INTERCEPTORS,
    useClass: ServerErrorInterceptor,
    multi: true
  }
]
  

Ответ №4:

Попробуйте это

 @Injectable()
export class HTTPListener implements HttpInterceptor {
  constructor(private status: HTTPStatus) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      map(event => {
        return event
      }),
      catchError(err => {
        if (err.status === 401) {
        }

        const error = err.error.message || err.statusText
        return throwError(error)
      }),
      finalize(() => {}),
    )
  }
}