通过拦挡,开发人员能够申明拦截器来检查和转换从应用程序到服务器的 HTTP 申请。 雷同的拦截器还能够在返回应用程序的途中检查和转换服务器的响应。

多个拦截器独特造成申请/响应处理程序的前向和后向链。

拦截器能够以惯例、规范的形式为每个 HTTP 申请/响应执行各种隐式工作,包含但不限于身份验证到日志记录。

如果没有拦截器的概念,开发人员将不得不为每个 HttpClient 办法调用显式地实现这些工作。

要实现拦截器,开发人员必须申明一个实现 HttpInterceptor 接口的 intercept() 办法的类。

上面是一个拦截器的实现,尽管拦挡了 HTTP 申请之后,并未执行任何逻辑,只是简略的把申请传递给后向链:

import { Injectable } from '@angular/core';import {  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';import { Observable } from 'rxjs';/** Pass untouched request through to the next request handler. */@Injectable()export class NoopInterceptor implements HttpInterceptor {  intercept(req: HttpRequest<any>, next: HttpHandler):    Observable<HttpEvent<any>> {    return next.handle(req);  }}

intercept 办法将申请转换为最终返回 HTTP 响应的 Observable。

大多数拦截器在进入的过程中查看申请,并将可能更改的申请转发到实现 HttpHandler 接口的下一个对象的 handle() 办法。

与 intercept() 一样,handle() 办法将 HTTP 申请转换为 HttpEvents 的 Observable,最终蕴含服务器的响应。 intercept() 办法能够查看该 observable 并在将其返回给调用者之前对其进行更改,比方增加日志记录,字段过滤等等逻辑。

看个具体的例子:

上图是 SAP Spartacus UI SiteContextInterceptor 的实现,关键点如上图图例1和2所示:

  1. 应用 request.url.includes(this.occEndpoints.getBaseUrl() 判断以后申请 url 是否蕴含 baseUrl 片段。
  2. 如果蕴含,应用 request.clone, 给以后 HTTP 申请,增加 language 和 curr 参数。

这两个主动增加的参数,成果如下:

url:http://aaa/occ/v2/electronics-spa/currencies?lang=en&curr=USD

next 对象代表拦截器链中的下一个拦截器。链中的最初一个是 HttpClient 后端处理程序,它将申请发送到服务器并接管服务器的响应。

大多数拦截器调用 next.handle() 以便申请流向下一个拦截器,最终流向后端处理程序。 拦截器能够跳过调用 next.handle(),使链短路,并返回本人的 Observable 和人工服务器响应。

这是 Express.js 等框架中常见的中间件模式。