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

Angular13如何根据HTTP请求发起位置为HTTP_INTERCEPTORS添加条件

实现方案

方案一:给初始化请求添加自定义Header(推荐)

通过在初始化阶段发起的HTTP请求中添加专属Header,拦截器据此识别并执行特定逻辑,不会影响其他请求。

1. 在Ngrx Effect中为初始化请求添加Header

处理MyAction.getData的Effect里,调用HTTP请求时注入自定义Header:

import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map, switchMap, catchError } from 'rxjs/operators';
import { of } from 'rxjs';
import * as MyAction from './actions';

@Injectable()
export class MyEffects {
  loadData$ = createEffect(() => 
    this.actions$.pipe(
      ofType(MyAction.getData),
      switchMap(() => 
        this.http.get('/api/data', {
          // 添加初始化请求专属Header
          headers: new HttpHeaders().set('X-App-Init-Request', 'true')
        }).pipe(
          map(data => MyAction.getDataSuccess({ data })),
          catchError(err => of(MyAction.getDataFailure({ err })))
        )
      )
    )
  );

  constructor(private actions$: Actions, private http: HttpClient) {}
}

2. 在拦截器中识别并处理

在MyHttpInterceptor里检查请求是否携带该Header,执行特定逻辑后可删除Header避免传递给后端:

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable, tap } from 'rxjs';

@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // 判断是否为初始化请求
    if (req.headers.has('X-App-Init-Request')) {
      // 执行初始化请求的特定逻辑(比如加载指示器、权限校验等)
      console.log('处理初始化阶段请求');
      
      // 克隆请求并删除自定义Header,避免传到后端
      const modifiedReq = req.clone({
        headers: req.headers.delete('X-App-Init-Request')
      });

      return next.handle(modifiedReq).pipe(
        tap(event => {
          // 初始化请求完成后的额外处理
        })
      );
    }

    // 非初始化请求直接放行
    return next.handle(req);
  }
}

方案二:通过状态服务标记初始化阶段

创建一个全局服务记录应用是否处于初始化状态,拦截器根据该状态判断请求类型。

1. 实现初始化状态服务

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class AppInitStateService {
  private _isInitializing = new BehaviorSubject<boolean>(false);
  isInitializing$: Observable<boolean> = this._isInitializing.asObservable();

  setInitializing(state: boolean): void {
    this._isInitializing.next(state);
  }
}

2. 在APP_INITIALIZER中更新状态

在app.module.ts的初始化函数中,标记初始化开始与结束:

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppInitStateService } from './app-init-state.service';
import * as MyAction from './actions';
import { selectDataLoaded } from './selectors';

export function appInitializer(store: Store, initStateService: AppInitStateService): () => Observable<any> {
  return () => {
    // 标记进入初始化阶段
    initStateService.setInitializing(true);
    return store.dispatch(MyAction.getData())
      .pipe(
        // 等待数据加载完成的状态
        concatLatestFrom(() => store.select(selectDataLoaded)),
        take(1),
        // 标记初始化结束
        tap(() => initStateService.setInitializing(false))
      );
  };
}

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: appInitializer,
      deps: [Store, AppInitStateService],
      multi: true
    }
  ]
})
export class AppModule {}

3. 在拦截器中根据状态处理请求

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable, switchMap, take } from 'rxjs';
import { AppInitStateService } from './app-init-state.service';

@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {
  constructor(private initStateService: AppInitStateService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.initStateService.isInitializing$.pipe(
      take(1),
      switchMap(isInitializing => {
        if (isInitializing) {
          // 执行初始化请求的特定逻辑
          return next.handle(req).pipe(
            tap(event => {
              // 额外处理逻辑
            })
          );
        }
        return next.handle(req);
      })
    );
  }
}

注意:方案二需注意异步时序问题,如果初始化请求未完成时组件发起其他请求,可能会误判。方案一通过请求级别的Header标记,更精准可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:35:23