You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 20中使用DI-based拦截器时API无法执行,页面长时间加载无响应

Angular 20中使用DI-based拦截器时API无法执行,页面长时间加载无响应

看起来你碰到了Angular 20结合SSR(服务端渲染)使用DI式HTTP拦截器时的请求阻塞问题,我来帮你理清楚问题根源和解决办法:

先确认:你的基础代码逻辑是没问题的

先给你吃个定心丸——你写的TokenInterceptor、app.config.ts里的拦截器注册,还有ProductService的API调用代码本身都是正确的:

  • 拦截器里注入TokenService、克隆请求添加Authorization头的逻辑没问题
  • app.config.ts里正确启用了withInterceptorsFromDi(),也按要求注册了HTTP_INTERCEPTORS提供商
  • 产品服务里的参数拼接和HTTP请求写法也符合Angular规范

问题的核心:SSR环境的特殊限制

你提到项目用了SSR(从app.routes.server.ts的预渲染配置能看出来),这就是关键!在SSR场景中,服务端渲染阶段的代码是跑在Node.js环境里的,没有浏览器的localStorage/sessionStorage这些API——而你的TokenService大概率是从这些浏览器存储里获取token的,这就导致服务端执行拦截器逻辑时,要么获取token失败抛出错误,要么因为尝试访问不存在的浏览器API卡住,进而阻塞了整个API请求流程,最终页面就一直加载没响应。

验证结论:排除SSR就正常

你已经做了最关键的测试:新建一个没有SSR的Angular项目,用同样的拦截器和API代码就能正常工作,这直接坐实了问题出在SSR和拦截器的交互上。

具体修复方案

针对SSR环境,我们需要让拦截器和TokenService区分“服务端”和“浏览器”环境来执行逻辑:

1. 修改TokenInterceptor,仅在浏览器环境下添加token

注入PLATFORM_ID来判断当前运行环境,只在浏览器里执行添加token的逻辑:

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
import { Injectable, Inject, PLATFORM_ID } from "@angular/core";
import { Observable } from "rxjs";
import { TokenService } from "../service/token.service";
import { isPlatformBrowser } from "@angular/common";

@Injectable()
export class TokenInterceptor implements HttpInterceptor { 
  constructor(
    private tokenService: TokenService,
    @Inject(PLATFORM_ID) private platformId: Object
  ) { }

  intercept( req: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> {
    // 仅在浏览器环境下尝试获取并添加token
    if (isPlatformBrowser(this.platformId)) {
      const token = this.tokenService.getToken();
      if (token) {
        req = req.clone({
          setHeaders: {
            Authorization: `Bearer ${token}`,
          }
        });
      }
    }
    return next.handle(req);
  }
}

2. 修复TokenService,避免服务端报错

确保TokenService在服务端环境下不会因为访问浏览器API报错:

import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class TokenService {
  getToken(): string | null {
    // 服务端环境直接返回null,避免访问localStorage报错
    if (typeof window === 'undefined') {
      return null;
    }
    return localStorage.getItem('token');
  }
}

3. 检查SSR服务端配置

确保你的SSR服务端代码(比如main.server.ts)里的HTTP客户端初始化也正确支持DI拦截器,避免服务端请求时出现死锁或未处理的Promise。

总结

你的代码在纯浏览器环境下完全正常,问题就是SSR场景中服务端无法处理浏览器特有的存储API,导致拦截器逻辑阻塞了请求。通过区分平台环境调整拦截器和TokenService的逻辑,就能解决页面长时间加载无响应的问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 08:39:37