【问题标题】:How to cancel current request in interceptor - Angular 4如何在拦截器中取消当前请求 - Angular 4
【发布时间】:2018-03-08 02:52:48
【问题描述】:

如您所知,可以在新版本的 Angular 4 中使用 拦截器

在我的情况下,我想在某些情况下取消拦截器中的请求。 那么有可能吗?或者我应该问的是,我应该以哪种方式做到这一点?

也会好的!如果我找到了一种方法来重写对请求的某些响应而不是取消它。

【问题讨论】:

  • “重写一些响应”是什么意思?如果您的意思是这样,在处理请求之前很容易对其进行编辑。
  • 文档有一个例子:angular.io/guide/http#caching
  • 我之所以提到这一点,是因为我在 stackoverflow.com/a/38926333/3534952 中看到了 angularjs 的一些特性。
  • @JBNizet 我一遍又一遍地查看文档!我认为文档中没有提到这个,或者我看不到它!我真正想要的是取消请求或者重写另一个响应,而不是从服务器获得什么。
  • 我链接到的文档有以下注释:缓存响应存在。服务它而不是将请求转发给下一个处理程序。因此它确实返回缓存的响应,而不是实际将请求发送到服务器。

标签: angular angular-http-interceptors


【解决方案1】:

我认为切断拦截器链所需要做的就是像这样简单地返回一个空的Observable

import { EMPTY } from 'rxjs';

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  if (stopThisRequest) {
    return EMPTY;
  }

  return next.handle(request);
}

【讨论】:

  • 在一个场景中,假设我有两个 rxJS 请求同时执行到后端,我想停止其中一个,我该如何使用拦截器来做到这一点? @RVP
  • 对于 RXJS 6,只需从 'rxjs' 导入 { EMPTY } 并返回 EMPTY。仅供参考,在 rxjs 中,EMPTY 不同于空。
  • httpclient拦截响应时如何取消响应,Observable.empty()不起作用
  • @Codehan25 你必须自己想出的逻辑。您可以使用 DI 在拦截器中注入您想要的任何服务,并将您的逻辑基于应用程序中可用的状态
  • 谢谢,这正是我想要的,对我帮助很大:)
【解决方案2】:

受@RVP 回答的启发,我发现可以使用Observable.throw() 以同样简单的方式切断错误链

//...
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (stopThisRequestWithError) {
        return Observable.throw('Error message');
    } else {
        return next.handle(req);
    }
}

这避免了使用未定义的值来履行响应承诺。

【讨论】:

  • 在一个场景中,假设我有两个 rxJS 请求同时执行到后端,我想停止其中一个,我该如何使用拦截器来做到这一点?
  • 这个答案(在当前版本的 RxJS 中使用 throwError)是唯一对我有用的东西。正如其他人所建议的那样,EMPTY 有一些令人讨厌的副作用,因为等待结果的代码从未运行过。
  • throwError(...) 现在
  • @Codehan25 只是我自己想出来的一个变量,需要根据需要自己设置条件。
【解决方案3】:

这只是RVP's 答案的轻微变体

import { NEVER } from 'rxjs';

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  if (stopThisRequest) {
    return NEVER;
  }

  return next.handle(request);
}

我使用NEVER 而不是EMPTY 来避免在我的订阅(或承诺)中处理未定义的值。

如果您不希望调用订阅回调,请使用 NEVER

【讨论】:

  • 通过在 Angular Universal 中使用它,应用程序将卡住并继续等待请求解决。
【解决方案4】:

对于 Angular 6,您需要使用以下结构来返回一个空的 Observable:

import {Observable} from 'rxjs';
import {empty} from 'rxjs/internal/Observer';

//...

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (stopThisRequest) {
        return Observable.create(empty);
    } else {
        return next.handle(req);
    }
}

【讨论】:

  • 你能详细说明什么是 Observable.create(empty);
  • Empty 是一个 RxJs 观察者,它取消请求但仍然返回一个有效的观察者。您可以通过以下导入将他添加到您的项目中: import {empty} from 'rxjs/internal/Observer';
【解决方案5】:

@RVP 的代码可以正常工作,我们可以再做一件事。

只添加return,它也可以工作

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
          if(helper.isTokenExpired(tokenVal)){
              return;
          }
        .
        . <{code}>
        .

    }

【讨论】:

  • 这对我不起作用 - 收到错误“您在预期流的位置提供了‘未定义’。您可以提供 Observable、Promise、Array 或 Iterable。”
【解决方案6】:

如上所述,有更优化的方法来处理自定义响应的错误

import { throwError, Observable } from 'rxjs';
import { HttpEvent } from '@angular/common/http';

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  if (authFailedDummy(request)) {
    return throwError(new Error('Authorization error: The request did not go through'));
  }
  return next.handle(request);
}

【讨论】:

    【解决方案7】:

    嘿,我想我迟到了,但想分享一些额外的知识

    如果您想在某个超时后取消请求,您可以在拦截器中使用 rxjs 超时运算符,它适用于每个请求。

      intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<unknown>> 
        {
        return next.handle(req).pipe(timeout(30000), 
        catchError((error: HttpErrorResponse) => {
          return throwError({ error: error.name, message: error.message});
        })) as Observable<HttpEvent<unknown>>
        }
    
    

    【讨论】:

      【解决方案8】:
      let sub = this.http.get(url, {headers: reqHeaders})
                  .subscribe(
                      (res) => {
                          res = res.json();
                      }
                  );
      
      sub.unsubscribe();
      

      【讨论】:

      • 感谢您的回答,但这不是解决方案!
      • 这不能在拦截器中完成,因为您没有订阅,而是 HttpRequest。
      • @maximeMorin,是的,你可以,如果你可以返回一个 Observable,你可以返回一个告诉你的订阅者取消订阅的 Observable。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-05
      • 2018-10-31
      • 1970-01-01
      • 2015-02-01
      • 2020-03-11
      • 2018-03-30
      相关资源
      最近更新 更多