#angular #typescript
#angular #typescript
Вопрос:
Я пытаюсь перехватить ответы, возвращающиеся от /api
, перехватить их, если они 401, выполнить действие обновления сеанса, затем снова повторить исходный HTTP-вызов (дополнительно предотвращая его бесконечное зацикливание, если он снова повторяется с 401)
Что, я думаю, я делаю в приведенном ниже коде, так это запускаю запрос с помощью http-обработчика, подписываюсь на его события и, если это не удается на 401, обновляю, затем возвращаю наблюдаемое значение клонированного запроса, выполняемого обработчиком.
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!request.url.startsWith('/api')) {
return next.handle(request)
}
const cloned = request.clone()
return next.handle(request)
.pipe(
catchError((error: any) => {
if (error.status !== 401) {
return throwError(error)
}
return from(this.sessionService.refresh())
.pipe(map(() => next.handle(cloned)))
})
)
}
Есть предложения о том, как я мог бы достичь того, что я пытаюсь?
Ответ №1:
Возможно, в этом есть несколько синтаксических ошибок, потому что я пишу с мобильного, но это должно помочь вам начать
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!request.url.startsWith('/api')) {
return next.handle(request)
}
const cloned = request.clone()
return next.handle(request)
.do((event: HttpEvent<any>) =>
return from(this.sessionService.refresh())
.pipe(map(() => next.handle(cloned)))
}), (err: any) => {
if (err instanceof HttpResponse) {
if(err.status === 401){
return throwError(error);
}
}
)
}
Ответ №2:
Ответ состоял в том, чтобы использовать switctMap
вместо map
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
{
if (!request.url.startsWith('/api')) {
return next.handle(request)
}
const cloned = request.clone()
return next.handle(request)
.pipe(
catchError((error: any) => {
if (error.status !== 401) {
return throwError(error)
}
return from(this.sessionService.refresh())
.pipe(switchMap(() => next.handle(cloned)))
})
)
}
Однако я выбрал альтернативный подход, при котором я проверяю, есть ли у меня сеанс, прежде чем произойдет запрос, вводя действие обновления, если требуется.
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (
!request.url.startsWith('/api') ||
this.sessionService.isValid
) {
return next.handle(request)
}
return from(this.sessionService.refresh())
.pipe(switchMap(() => next.handle(request)))
}