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

Angular中如何通过HttpInterceptor实现无网络时显示自定义组件

解决方案

你可以通过全局共享状态服务的方式,在拦截器中更新网络状态,所有需要感知网络状态的组件直接订阅服务即可,不需要每个组件单独做网络检测。

实现步骤

  • 第一步:创建全局网络状态共享服务
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class NetworkStatusService {
  // 初始值取当前设备的网络状态
  private isOnlineSub = new BehaviorSubject<boolean>(window.navigator.onLine);
  // 对外暴露可订阅的状态流
  public isOnline$ = this.isOnlineSub.asObservable();

  // 更新网络状态
  setOnlineStatus(status: boolean) {
    this.isOnlineSub.next(status);
  }

  constructor() {
    // 可选:监听浏览器原生的网络变化事件,无需等待请求发起即可实时更新状态
    window.addEventListener('online', () => this.setOnlineStatus(true));
    window.addEventListener('offline', () => this.setOnlineStatus(false));
  }
}
  • 第二步:修改HttpInterceptor,注入服务更新状态,同时修正原有逻辑问题
    原拦截器中无网时直接return会返回undefined,导致上游订阅抛出类型错误,需要修改为返回错误Observable:
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { NetworkStatusService } from './network-status.service'; // 替换为你实际的服务路径

@Injectable()
export class ServiceInterceptor implements HttpInterceptor {

  constructor(private networkStatusService: NetworkStatusService) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    req = req.clone({
      setHeaders: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      }
    });

    // 更新当前网络状态
    this.networkStatusService.setOnlineStatus(window.navigator.onLine);
 
    if (!window.navigator.onLine) {
      console.log("no internet connection");
      // 抛出无网错误,上游请求订阅可直接捕获
      return throwError(() => new Error('无网络连接'));
    }
    
    return next.handle(req);
  }
}
  • 第三步:在Home组件中订阅网络状态,控制自定义无网组件显示
import { Component, OnInit, OnDestroy } from '@angular/core';
import { DataService } from '../data.service';
import { NetworkStatusService } from '../network-status.service'; // 替换为你实际的服务路径
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {
  products = [];
  isOnline = true;
  private networkSub?: Subscription;

  constructor(
    private dataService: DataService,
    private networkStatusService: NetworkStatusService
  ) { }

  ngOnInit() {
    // 订阅网络状态变化
    this.networkSub = this.networkStatusService.isOnline$.subscribe(status => {
      this.isOnline = status;
    });

    this.dataService.sendGetRequest().subscribe({
      next: (data: any) => {
        console.log(data);
        this.products = data;
      },
      error: (err) => {
        console.log('请求出错:', err.message);
      }
    });
  }

  ngOnDestroy() {
    // 取消订阅避免内存泄漏
    this.networkSub?.unsubscribe();
  }
}

对应home.component.html 用法示例:

<!-- 无网时展示自定义离线组件 -->
<app-your-offline-component *ngIf="!isOnline"></app-your-offline-component>

<!-- 有网时展示正常业务内容 -->
<div *ngIf="isOnline">
  <div *ngFor="let product of products">
    {{ product | json }}
  </div>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 21:39:00