通过拦截,开发者可以声明拦截器来检查和转换从应用程序到服务器的HTTP请求。同一个拦截器还可以在返回应用程序的过程中检查和转换服务器的响应。多个拦截器一起形成请求/响应处理程序的前向和后向链。拦截器可以以常规、标准的方式为每个HTTP请求/响应执行各种隐式任务,包括但不限于身份验证到日志记录。如果没有拦截器的概念,开发人员将不得不为每个HttpClient方法调用显式地实现这些任务。要实现拦截器,开发人员必须声明一个实现HttpInterceptor接口的intercept()方法的类。下面是一个拦截器的实现。虽然它在拦截HTTP请求后不执行任何逻辑,但它只是将请求传递给反向链:import{Injectable}from'@angular/core';import{HttpEvent,HttpInterceptor,HttpHandler,HttpRequest}from'@angular/common/http';import{Observable}from'rxjs';/**将未触及的请求传递给下一个请求处理程序。*/@Injectable()exportclassNoopInterceptorimplementsHttpInterceptor{拦截(req:HttpRequest,next:HttpHandler):Observable>{returnnext.handle(req);}}拦截方法将请求转换为最终返回HTTP响应的Observable。大多数拦截器会检查传入的请求,并将可能更改的请求转发给实现HttpHandler接口的下一个对象的handle()方法。与intercept()一样,handle()方法将HTTP请求转换为HttpEvents的Observable,最终包含服务器的响应。intercept()方法可以检查可观察对象并在将其返回给调用者之前对其进行更改,例如添加日志记录、字段过滤和其他逻辑。看一个具体的例子:上图是SAPSpartacusUISiteContextInterceptor的实现,关键点如上图1和图2所示:使用request.url.includes(this.occEndpoints.getBaseUrl())判断当前是否请求url包含baseUrl片段。如果包含,则使用request.clone将language和curr参数添加到当前HTTP请求中。这两个自动添加的参数有以下作用:url:http://aaa/occ/v2/electronics-spa/currencies?lang=en&curr=USDnext对象表示拦截器链中的下一个拦截器。链中的最后一个是HttpClient后端处理程序,它向服务器发送请求并从服务器接收响应。大多数拦截器调用next.handle()以便请求流向下一个拦截器,最终流向后端处理程序。拦截器可以跳过调用next.handle()、短路链并返回自己的Observable和人工服务器响应。这在Express.js中间件模式等框架中很常见。