如何在http拦截器Angular中处理/检测取消的请求?

问题描述 投票:0回答:4

如何在http拦截器中处理取消的请求?我尝试过SO的各种方法,但似乎没有一个能抓住它。

这就是我的拦截器的样子,

public intercept(req: HttpRequest<any>, next: HttpHandler) {
        const xyz = this._cookieService.get('xyz');
        const abc = this._cookieService.get('abc');

        let authReq;
        if (jwt === "undefined" || jwt === undefined) {
            authReq = req.clone({ headers: req.headers.set('Authorization', xyz) });
        } else {
            authReq = req.clone({setHeaders: { Authorization: 'bearer ' + abc } });
        }

        return next
            .handle(authReq)
            .pipe(
                catchError((err: HttpErrorResponse) => this.catchErrorHandler(err))
            );
    }

我也尝试过

do
finalize
方法。就是这样,我的授权过期了,之后的所有请求就一一崩溃了,分页了。我想用代码来处理它,这样页面就不会中断。 我尝试过的方法: https://stackoverflow.com/a/50620910/6630504 https://stackoverflow.com/a/55756885/6630504

javascript angular typescript angular-http-interceptors
4个回答
2
投票

有一个名为 finalize 的 RxJS 运算符。

返回一个镜像源 Observable 的 Observable,但会 当源完成或终止时调用指定的函数 错误。当订阅者订阅时,指定的函数也会被调用 明确取消订阅。

    return next
        .handle(authReq)
        .pipe(
            catchError((err: HttpErrorResponse) => this.catchErrorHandler(err)),
            finalize(() => console.log('finalize'))
        );

0
投票

试试这个拦截器:

@Injectable()
export class RequestInterception implements HttpInterceptor {
  public constructor() { }

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const token = '';
    const currentLanguage = 'en';
    let headers;

    if (token) {
      headers = new HttpHeaders({
        "X-MDM-Token": token,
        "Accept-Language": currentLanguage
      });
    }

    request = request.clone({
      headers: headers,
      url: request.url || environment.serverUrl
    });

    return next.handle(request).pipe(
      map((event: any) => {

        if (event.status < 200 || event.status >= 300) {
          return Observable.throw(event);
        }

        return event;
      }),

      catchError((response: HttpErrorResponse, request) => {
        switch (response.status) {
          case 401:
            //
            break;
        }
        return throwError("Ошибка сервера RequestInterception!");
      })
    );
  }
}

如果客户端取消http请求,您将获得499 http代码,它将被以下方式捕获:

if (event.status < 200 || event.status >= 300) {
      return Observable.throw(event);
}

0
投票

我是这样做的:

拦截器代码:

...
return next.handle(request)
  .pipe(
    onCancelled(() => {
      // request cancelled callback
    }),
  );
...

onCancelled 函数

function onCancelled<T>(callback: () => void) {
  return (obs: Observable<T>) => {
    let cancelled = true;
    return new Observable<T>(subscriber => {
      const sub = obs.subscribe(
        value => {
          if (value instanceof HttpResponse) cancelled = false;
          subscriber.next(value);
        },
        err => {
          cancelled = false;
          subscriber.error(err);
        },
        () => {
          cancelled = false;
          subscriber.complete();
        });
      return () => {
        if (cancelled) callback();
        sub.unsubscribe();
      };
    });
  };
}

0
投票

我想知道同样的事情有一段时间了,并决定今天研究一下。

记录已取消的请求时,错误如下所示:

{
    "headers": {
        "normalizedNames": {},
        "lazyUpdate": null,
        "headers": {}
    },
    "status": 0,
    "statusText": "Unknown Error",
    "url": "https://localhost:7258/api/company/test-exception",
    "ok": false,
    "name": "HttpErrorResponse",
    "message": "Http failure response for https://localhost:7258/api/company/test-exception: 0 Unknown Error",
    "error": {
        "isTrusted": true
    }
}

注意标头为空,状态代码为

0

当我搜索状态代码

0
的含义时,我发现了这个:

实际上,失败的 XmlHttpRequest 的 status==0 应被视为未定义错误。

此代码可能是在联系服务器之前发生的错误的结果。

whitneyland 回答,HTTP 请求返回状态代码 0 是什么意思?

虽然我们仍然需要确定状态

0
的原因,但我们可以简单地通过以下方式捕获此错误:

next
  .handle(req)
  .pipe(
  catchError((err) => {
    if (err.status == 0) {
      // handle cancelled request here
      console.log(err);
    }
  }
})
© www.soinside.com 2019 - 2024. All rights reserved.