如何在Angular路由解析器的RxJS expand中检查HTTP状态码?
问题描述
需要在Angular路由的数据守卫(resolver)中实现以下逻辑:
- 发起一个GET请求,检查其返回的状态码
- 若状态码为204,则调用另一个API
- 不能使用
subscribe方法,希望通过expand操作符实现,但不清楚如何获取请求的状态码
给出的示例代码:
const obs = this.http.get(url); return obs.pipe( expand((data: any) => { console.log(data); return from(data); }), );
解决方案
要实现这个逻辑,核心是先获取HTTP请求的完整响应(包含状态码),再通过expand操作符判断是否需要发起后续请求。
关键步骤说明
- 获取完整HTTP响应:默认情况下Angular的
HttpClient.get()只返回响应体,需要添加{ observe: 'response' }选项,这样会返回HttpResponse对象,其中包含status状态码属性。 - 使用
expand递归处理请求:在expand中判断响应状态码,若为204则发起第二个API请求,否则返回EMPTY终止流。 - 适配Resolver要求:Resolver需要返回最终的数据,因此要提取响应体,并确保Observable只发出最后一个有效数据。
完整代码示例
import { Injectable } from '@angular/core'; import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable, EMPTY, last, map, expand } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataResolver implements Resolve<any> { constructor(private http: HttpClient) {} resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> { const primaryApiUrl = '你的第一个API地址'; const fallbackApiUrl = '你的备用API地址'; // 发起第一个请求,获取完整响应 return this.http.get(primaryApiUrl, { observe: 'response' }).pipe( expand((response: HttpResponse<any>) => { // 判断状态码是否为204 if (response.status === 204) { // 状态码204时,发起第二个API请求 return this.http.get(fallbackApiUrl, { observe: 'response' }); } // 非204状态,终止递归流 return EMPTY; }), // 提取响应体数据 map(response => response.body), // 确保只返回最后一个有效数据(适配Resolver的单值需求) last() ); } }
补充说明
- 如果备用API也可能返回204,可以在
expand中继续添加判断逻辑,实现多级递归调用。 last()操作符确保Resolver最终只返回一个值,避免路由收到多个数据通知。- 若不需要处理后续请求的状态码,备用API请求可以去掉
{ observe: 'response' },直接返回响应体,但这样expand的参数会变成响应体,无法再判断状态码。
内容的提问来源于stack exchange,提问作者dman
相关产品推荐
相关产品推荐

