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

Angular 19使用provideAppInitializer获取CSRF Token Cookie故障排查

问题排查与修复方案

核心错误1:Promise未正确触发状态变更

你的fetch_token方法创建了Promise,但在HTTP请求完成后没有调用resolve或reject,导致这个Promise永远处于pending状态。Angular的provideAppInitializer需要依赖返回的Promise来判断初始化是否完成,现在的代码等于没让应用等待Token请求结束。

修复CsrfService的fetch_token方法:

fetch_token(): Promise<void> {
  return new Promise((resolve, reject) => {
    // 注意补充完整请求协议与端口,比如http://localhost:8000/xxx
    this.http.get<{ token: string }>('http://localhost:8000/api/get-csrf-token', { withCredentials: true })
      .subscribe({
        next: (response) => {
          this.token = response.token;
          resolve(); // 请求成功后标记Promise完成
        },
        error: (error) => {
          console.error('Error fetching CSRF token', error);
          reject(error); // 请求失败时标记Promise异常
        },
      });
  });
}

核心错误2:初始化器未返回Promise

在provideAppInitializer的回调里,你调用了fetch_token但没有返回这个Promise,Angular无法追踪异步操作的完成状态,自然不会等待Token请求完成就启动应用。

修复app.config.ts的初始化器配置:

provideAppInitializer(() => {
  return inject(CsrfService).fetch_token(); // 返回Promise,让Angular等待初始化完成
})

额外优化:贴合Django CSRF规范的简化方案

其实你不需要手动存储Token,Django的CSRF机制只需要两点就能自动处理:

  1. 所有请求携带withCredentials: true,让浏览器自动保存并发送CSRF Cookie
  2. 配置Angular HTTP拦截器,自动从Cookie中读取csrftoken并添加到请求头X-CSRFToken

示例拦截器代码:

import { HttpInterceptorFn } from '@angular/common/http';

export const csrfInterceptor: HttpInterceptorFn = (req, next) => {
  // 仅对非安全请求(非GET/HEAD/OPTIONS)添加CSRF头
  if (!req.method.match(/GET|HEAD|OPTIONS/)) {
    const csrfToken = document.cookie.split('; ')
      .find(row => row.startsWith('csrftoken='))
      ?.split('=')[1];
    
    if (csrfToken) {
      req = req.clone({
        headers: req.headers.set('X-CSRFToken', csrfToken)
      });
    }
  }
  return next(req);
};

然后在app.config.ts中注册拦截器:

provideHttpClient(withInterceptors([csrfInterceptor])),

只要你的Django后端通过CsrfViewMiddleware中间件(或自定义接口)正确设置了CSRF Cookie,浏览器会自动处理Cookie的存储与携带,甚至不需要手动调用初始化接口。

其他注意事项

  • 请求URL必须完整:localhost/fake/url要补充协议(如http://)和对应端口(如8000),否则浏览器会解析错误
  • 确保前后端同域:域名、端口、协议必须完全一致,否则Cookie无法正常跨域携带

内容的提问来源于stack exchange,提问作者user25752829

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 00:02:04