首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果HTTP响应为401,则角重定向页

如果HTTP响应为401,则角重定向页
EN

Stack Overflow用户
提问于 2020-11-17 14:33:34
回答 2查看 1.9K关注 0票数 2

我在我的角(10)应用程序中发送多个API请求。如果其中一个请求返回状态401的响应,我希望将页面重定向到我的登录页面(从组件页面)。

我有一个负责API调用的服务,它有以下两个方法:

代码语言:javascript
复制
    export class ApiService {
    constructor(private http: HttpClient){
}
      public get<T>(path: string, params: HttpParams = new HttpParams(), headers: HttpHeaders = new HttpHeaders()): Observable<T> {
        return this.getBodyOfResponseOrRedirect(
          this.http.get<T>(path, {headers, params, observe: 'response'}));
      }
    
      private getBodyOfResponseOrRedirect<T>(responseObservable: Observable<HttpResponse<T>>): Observable<T> {
        return responseObservable.pipe(map(response => {
          if (response.status === 401) {
            window.location.href = 'https://custom-url';
          } else {
            return response.body;
          }
        }));
      }

现在,我尝试在另一个服务中使用API服务方法:

代码语言:javascript
复制
 export class ShopDataService{
  ...
  getShopsData(): Observable<Shop[]> {
    return this.apiService.get<Shop[]>("https://shops.com/v1/endpoint)
      .pipe(
        tap(data => console.log('shop recieved : ' + JSON.stringify(data))),
        catchError(this.handleError)
      );
  }

  private handleError(err: HttpErrorResponse) {
    let errorMessage = '';
    errorMessage = `Server returned code : ${err.status}, error message is : ${err.message}`;
    console.error(errorMessage);
    return throwError(errorMessage);
  }

当响应状态为401时,重定向无法工作,相反,我在控制台中看到:

main.gb7558h03a743440f512.js:1服务器返回代码: 401,错误消息是:https://shops.com/v1/endpoint的Http失败响应: 401 OK

我做错什么了?

这里的主要想法是,当我加载组件时,我的auth令牌是有效的。过了一段时间,我的令牌过期了,但我没有刷新或移动到另一个页面。因此,当前的页面功能可能发送带有无效令牌的api请求,并将得到401错误的响应。我想处理一下这种行为。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-17 14:43:00

该401未经授权的响应通常以error通知的形式从角HttpClient发出。因此,您需要使用RxJS catchError操作符来捕获错误并重定向。然后,您可以发出NEVER常数,以便在重定向之后没有任何东西发出,并保持可观察到的活动,或者发出EMPTY常数来完成可观测的操作。

尝试以下几点

代码语言:javascript
复制
import { throwError, NEVER } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

export class ApiService {
  constructor(private http: HttpClient) { }
  
  public get<T>(
    path: string, 
    params: HttpParams = new HttpParams(), 
    headers: HttpHeaders = new HttpHeaders()
  ): Observable<T> {
    return this.getBodyOfResponseOrRedirect(
      this.http.get<T>(path, {headers, params, observe: 'response'}));
  }

  private getBodyOfResponseOrRedirect<T>(
    responseObservable: Observable<HttpResponse<T>>
  ): Observable<T> {
    return responseObservable.pipe(
      catchError(error => {
        if (!!error.status && error.status === 401) {
          window.location.href = 'https://custom-url';
          return NEVER;            // <-- never emit after the redirect
        }
        return throwError(error);  // <-- pass on the error if it isn't 401
      }),
      map(response =>  response.body)
    );
  }
}
票数 4
EN

Stack Overflow用户

发布于 2020-11-18 13:00:13

@Michael解决方案非常有用。根据他的评论,我实现了以下http拦截器:

代码语言:javascript
复制
@Injectable()
export class HttpResponseInterceptor implements HttpInterceptor {

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(catchError(error => {
      if (!!error.status && error.status === 401) {
        window.location.href = 'url';
        return NEVER;
      }
      return throwError(error);
    }));
  }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64877273

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档