Angular 6 Http拦截器异常:初始请求无法抵达服务器求助
问题分析与解决方案
首先来说说你的拦截器为什么会阻止初始请求:
- 你用了
map操作符,但这个操作符必须返回一个值来传递给流的下一个环节。当事件不是HttpResponse的时候(比如请求发送时的HttpSentEvent、响应头返回的HttpHeaderResponse等),你的代码没有返回任何内容,这就导致整个Observable流被中断了,所以初始请求的事件根本没法正常传递到后端,看起来像是被阻止了。 - 另外还有一个关键点:浏览器会自动处理HTTP 302重定向,Angular的
HttpClient默认也会跟随这个重定向,所以你大概率根本捕获不到302状态码的HttpResponse——因为浏览器已经自动跳转到重定向目标了,拦截器拿到的是重定向后的响应。
修正后的拦截器代码
我们需要做两个核心调整:
- 用
tap代替map:tap用于执行副作用操作(比如打印日志、跳转页面),不会修改或中断Observable流,完全适配这种只需要监听响应的场景。 - 如果确实需要捕获302,要在请求时配置
followRedirects: false,告诉HttpClient不要自动跟随重定向,这样才能拿到302的响应(否则浏览器会直接处理重定向,拦截器根本看不到这个状态码)。
@Injectable() export class ResponseHandler implements HttpInterceptor{ constructor(){} intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // 复制请求并添加不跟随重定向的配置(按需启用) const modifiedRequest = request.clone({ followRedirects: false }); return next.handle(modifiedRequest).pipe( tap((event: HttpEvent<any>) => { if(event instanceof HttpResponse){ if(event.status === 302){ console.log('HttpResponse 302 status detected'); window.location.href = '/home'; // 直接跳转到首页,比reload更精准 } } }), // 补充处理:设置followRedirects: false后,302会被当作错误抛出 catchError(err => { if(err.status === 302){ console.log('302 redirect caught in error handler'); window.location.href = '/home'; } return throwError(() => err); }) ); } }
额外注意事项
- 当设置
followRedirects: false后,HttpClient会把302当作错误抛出,所以必须在catchError里同步处理这个场景,这是很容易遗漏的细节。 - 直接使用
window.location.href = '/home'比window.location.reload()更符合你的需求:reload是重新加载当前页面,而你需要的是主动跳转到首页。 - 移除拦截器后请求恢复正常,本质原因就是原代码里的
map操作符吞掉了非HttpResponse类型的事件,导致整个请求流被截断;换成tap后,所有事件都会原封不动地向下传递,不会影响正常请求流程。
内容的提问来源于stack exchange,提问作者Atul
相关产品推荐
相关产品推荐

