angular http 拦截器 - 中止响应

angular http interceptor - abort response

有没有办法使用 angular 的 http 拦截器来拦截响应,然后将其删除/丢弃,以便以后不执行下游回调?

我希望它的行为使得 console.log 都不会被执行。

this.http.get('/foo').subscribe(
    data => console.log("success", data),
    err => console.log("fail.", err)
);

我见过修改响应或用 null 或其他标记值替换响应的示例,但我宁愿不这样做,因为那样我的所有 success/fail 处理程序都必须查找sentinel,它降低了使用拦截器处理某些响应的有用性。

我觉得这更像是一个 rxjs 问题,而不是 angular 拦截器问题,但我对 rx 还不够熟悉,还不能确定。

如果重要的话,我正在使用 angular 5.1

您可以使用 Observable.empty 完成流而不发出任何数据。要将其与 HttpInterceptor 组合,请将其链接到 next.handle:

return next.handle(req).switchMap(() => Observable.empty());

我不知道如何使用 Promise,抱歉。

我发现了另一种方法可以防止调用 subscribe() 回调。这是一个示例拦截器,如果某个 http header 出现在 HttpResponse.

中,它将避免调用下游订阅者

请注意,此方法并非真正 "throw the response away"。相反,它会无限期地延迟响应。如果您有使用计时器的代码(例如,如果在 60 秒内既没有收到成功响应也没有收到错误响应,则某些代码会出错),这可能是个问题,因为这正是此方法的工作原理 - 它只是从不响应。

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
        switchMap((event: HttpEvent<any>) => {

            // In this example, I only care about checking valid http responses.
            // But, if you also want to inspect errors, you might consider checking for HttpResponseBase or HttpErrorResponse
            if (event instanceof HttpResponse) {

                // Check if this response has a certain http response header set.
                // If so, we throw the response away.
                if (event.headers.has('my-custom-header')) {
                    // We intentionally return an Observable that will never complete. This way,
                    // downstream subscribers will never receive anything, and any .toPromise()
                    // conversions that may be present will also never be invoked because toPromise() only
                    // gets invoked when the Observable completes.
                    // It doesn't actually throw the response away, but rather, it makes the subscribers wait forever, so they will never get a response.
                    // Be careful if you use timeouts.
                    return new Subject<HttpEvent<any>>();
                }

            }

            // The default case - we pass the response back through unmodified.
            return Observable.of(event);
        })
    );
}

// These console.logs will not be called
this.http.get('/foo').subscribe(
    data => console.log("success", data),
    err => console.log("fail.", err)
);

// Neither will these
this.http.get('/foo').toPromise(
    data => console.log("success", data),
    err => console.log("fail.", err)
);