【问题标题】:angular interceptor logout the app if there is an 401 response?如果有 401 响应,角度拦截器会注销应用程序吗?
【发布时间】:2025-12-13 17:45:02
【问题描述】:

在我的拦截器中,如果响应 statusCode 为 401,我想在响应上放置一个管道并注销,但问题是当我放置一个 catchError 时,observable 不是 HttpEvent 类型并且拦截函数期望返回该类型?

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authToken = `Agency ${this.auth.token}`;
    const requestWithHeaders = req.clone({ setHeaders: {'Content-Type': 'application/json'}});
    if (!!this.auth.token) {
        const authReq = requestWithHeaders.clone({ setHeaders: { Authorization: authToken} });
        return next.handle(authReq).pipe(
            catchError(er => {
                if (er.status === 401) {
                    this.auth.logout();
                }
                return er;
            })
        );
    } else {
        return next.handle(requestWithHeaders);
    }
}

}。

【问题讨论】:

  • 创建注销路径并导航。

标签: angular typescript angular-http-interceptors


【解决方案1】:

抛出一个新的错误,它将被转发而不是仅仅返回错误:

import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators'

...

catchError(er => {
    if (er.status === 401) {
        this.auth.logout();
    }
    return throwError(er);
})

【讨论】:

    【解决方案2】:

    您可以使用以下方法处理您的Error 回复,试试这个

       return next.handle(clonedRequest).do((event: HttpEvent<any>) => {}, (error: any) => {
          if (error instanceof HttpErrorResponse) {
               if (error.status == 401 || error.status == 403) {
                 this.auth.logout();
             }
          }
       });
    

    我希望这能解决你的问题:)

    【讨论】:

    • 此代码适用于旧版本的 rxjs 新版本是 tap 并且应该在管道内。 tx 为您提供帮助
    • @Az264 我建议在pipe() 中使用catchError(),在这种情况下比tap(()=&gt;{}, (error:any)=&gt;{}) 更优雅。
    【解决方案3】:

    我就是这样做的。

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        //   const  newReq= req.clone({headers: req.headers.set('source', 'WEB')});
      const  newReq = req.clone({
            headers: new HttpHeaders({
                'source': 'WEB',
                'Authorization': localStorage.getItem(TOKEN) || ''
            })
        });
        return next.handle(newReq).pipe(map((e: HttpEvent<any>) => {
            if (e instanceof HttpResponse) {
        /*        console.error(e);
                console.log(e.status);*/
                if (e.status === 401) {
                    throw new Error('invalid token');
                }
            }
            return e;
        }));
    }
    

    if (e instanceof HttpResponse) this me that if its response>> 如果它的响应那么做你喜欢的验证。这里我只是抛出错误但我们可以清除保存的令牌并重定向到登录页面

    【讨论】: