简体   繁体   English

Angular拦截器如何防止重复请求?

[英]How to prevent duplicated requests for interceptor in Angular?

I have an interceptor which intercepts the 401 error codes received from a 200 OK message.我有一个interceptor ,它拦截从200 OK消息接收到的401错误代码。

Unfortunately, I can't modify the API server to return 401 error instead of 200 OK with error code.不幸的是,我无法修改API服务器以返回401错误而不是带有错误代码的200 OK

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
  switchMap((result: any) => {
    //401 unauthorized error message
    if (result && result.body && result.body.isSuccess == false && result.body.errorCode == '401') {
      return this.unAuthorizedError(request, next);
    } else {
      return next.handle(request);
    }
  }),
  catchError((error) => {
    if (error instanceof HttpErrorResponse) {
      switch ((<HttpErrorResponse>error).status) {
        case 401:
        case 403:
          return this.unAuthorizedError(request, next);
        default:
          break;
      }
    }
    return throwError(error);
  })
);
}

The problem is that every request is send twice and I assume that this is probably due to switchMap method which returns next.handle(request) .问题是每个请求都发送了两次,我认为这可能是由于返回next.handle(request)switchMap方法。

I tried with tap method我尝试了tap方法

 tap((result: any) => {
    //401 unauthorized error message
    if (result && result.body && result.body.isSuccess == false && result.body.errorCode == '401') {
      return this.unAuthorizedError(request, next);
    }
  }),

which sends the request only once, but when the token expires then this.unAuthorizedError(request, next) is not called.它只发送一次请求,但是当令牌过期时,不会调用this.unAuthorizedError(request, next)

I think you're right, what next.handle(request);我认为你是对的,什么next.handle(request); does is to make the request again.做的是再次提出请求。

When switchMap 's inner observable is created, you already have a response, so I'd say you can replace next.handle() with of(response) so that it can be consumed by which part initiated the request:当创建switchMap的内部可观察对象时,您已经有了一个响应,所以我想说您可以用of(response)替换next.handle() ) 以便它可以由发起请求的部分使用:

/* ... */
return next.handle(request).pipe(
  switchMap((result: any) => {
    //401 unauthorized error message
    if (result && result.body && result.body.isSuccess == false && result.body.errorCode == '401') {
      return this.unAuthorizedError(request, next);
    } else {
      return of(result);
    }
  }),
)
/* ... */

I wrote an article about Angular's HTTPClientModule , here's the section in which I talk about interceptors.我写了一篇关于 Angular 的HTTPClientModule的文章, 这里是我谈论拦截器的部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM