#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(() => {}),
)
}
}