在 Angular 的开发中,我们经常使用 HttpInterceptor 来扩展请求和响应。HttpInterceptor 可以在请求和响应的过程中进行修改,以便把额外的信息打包进去,或者在拦截器触发后重试 http 请求。RxJS 是 Angular 中一个核心的库,可以用来处理异步的事件流,它能够帮助我们在请求和响应中使用 HttpInterceptor。本文将介绍在使用 RxJS 和 HttpBackend 时遇到的问题,并展示解决方法。
背景
在 Angular 中使用 HttpInterceptor 可以对所有的 http 请求进行统一处理,这是因为我们可以在它的拦截函数中对请求进行修改。HttpInterceptor 的拦截函数返回值必须为 Observable<HttpEvent<any>>,它会被 RxJS Host 做一些特殊的处理,以便保持与 http 的方法 signature 相同。
当在 HttpInterceptor 中使用 HttpClient 时,它会创建一个 http 请求,并返回给我们一个 HttpResponse 对象。但是,当我们在 HttpInterceptor 中再次使用 HttpClient,HttpClient 会自动调用之前创建的请求,并返回响应。这样,多个拦截器就会使用同一个请求,导致请求被重复发送。
为了解决这个问题,我们需要在 HttpBackend 上创建一个新的请求。这样,每个拦截器都会使用自己的请求,从而避免请求被重复发送。
问题
在使用 RxJS 的 observe 方法时,可能会遇到无法拦截 http 请求的情况。这是因为 observe 方法返回 'response',而不是 HttpEvent。
例如:
-- -------------------- ---- ------- ------------- ------ ----- -------------------- ---------- --------------- - ------------------- ----- ----------- -- ------------------ ----------------- ----- ------------- -------------------------- - ----- ----------- - --------------- -------- ------------------------------------ ------- ---------- --- ------ ------------------------------------------------ - -------- ---------- -- --- ------ ---------- -------- ------------ -- - ----------------- ------- ---------- --------------- --- -- ------- --- -------- ------- ------------ -- ------------------------ -- - -
上面的代码会在获取用户资料后继续发送拦截器中的原始请求。但是,observe 返回的是 'response',而不是 HttpEvent。这意味着拦截器无法对响应进行修改。
解决方法
为了解决这个问题,我们可以使用 HttpBackend 来发送请求,而不是 HttpClient。HttpBackend 是在 Angular 中发起 http 请求的底层机构,它是 HttpClient 的底层实现。
我们可以在拦截器中注入 HttpBackend 并使用它来发送请求。然后,我们可以使用 next.handle(authRequest),通过管道链接拦截器链。
下面是一个示例代码,其中使用了 HttpBackend 相应地发送请求:
-- -------------------- ---- ------- ------------- ------ ----- -------------------- ---------- --------------- - ------------------- ------------ ------------ -- ------------------ ----------------- ----- ------------- -------------------------- - ----- ----------- - --------------- -------- ------------------------------------ ------- ---------- --- -- ---- --- -------- ------- ------- ----------- ------ -------------------------------------- ------------ -- - --------------------- ----------- ---------- --- -- --- --------- -- ------- --- -------- ------- ------------ -- ------------------------- -- - -
在上面的代码中,我们使用 HttpBackend 来发送原始请求,然后通过 switchMap 连接拦截器链。这样就可以避免使用 HttpClient 时出现的重复请求问题。并且使用 HttpBackend 的好处是我们可以直接访问 HttpBackend 的属性,例如 withCredentials 和 responseType。请注意,使用 HttpBackend 时,我们也可以使用 observe,这样拦截器就可以在响应上做操作了。
总结
使用 RxJS 和 HttpBackend 处理 http 拦截器是 Angular 前端开发的一个常见问题。通过使用 HttpBackend,我们可以避免出现多次发送请求的情况,并能更好地控制 http 请求。在本文中,我们介绍了使用 HttpBackend 并通过 switchMap 连接拦截器链的方法。这种方法可以解决 RxJS 无法拦截 'response' 的问题,能够完美地实现拦截器功能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64ff873195b1f8cacddf2446