Angular拦截器异步操作失效:HTTP请求未发起问题排查
解决Angular拦截器中等待accessToken后请求未触发的问题
嘿,我看了你的代码,问题其实出在创建accessToken$的方式上!
你用了from("accessToken"),但RxJS的from操作符对字符串的处理和你想的不一样——它会把字符串拆成单个字符逐个发射(比如"accessToken"会变成a、c、c、e...这样依次发射)。这就导致你的mergeMap会被调用N次(等于字符串长度),每次都克隆请求并尝试发送,这种异常的流行为很可能就是请求没正常触发的原因。
修复步骤
把from换成of操作符,of会直接把整个字符串作为单个值发射,这样mergeMap只会执行一次,完美实现你想要的"等accessToken就绪后再发请求"的逻辑:
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // 用of替代from,确保整个accessToken作为单一值发射 const accessToken$: Observable<string> = of("accessToken"); return accessToken$.pipe(mergeMap((accessToken: string) => { const clonedReq = req.clone({ setHeaders: { 'Authorization': `${accessToken}`, } }); return next.handle(clonedReq); })); }
额外注意事项
- 如果你的
accessToken$实际是从异步源获取的(比如本地存储、API请求),确保这个Observable只会发射一次值(可以用take(1)或者确保源是单播的),避免重复发送请求。 - 可以加上错误处理逻辑,比如当获取accessToken失败时,返回错误Observable或者跳转到登录页:
return accessToken$.pipe( mergeMap(accessToken => { const clonedReq = req.clone({ setHeaders: { 'Authorization': accessToken } }); return next.handle(clonedReq); }), catchError(error => { // 处理accessToken获取失败的情况,比如跳转登录 console.error('获取accessToken失败:', error); return throwError(() => new Error('认证失败')); }) );
内容的提问来源于stack exchange,提问作者Raz Ronen
相关产品推荐
相关产品推荐

