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

Angular组件跳转时MJPEG图片请求未终止问题求助

Angular组件销毁时取消MJPEG流请求的解决方案

你遇到的问题是MJPEG流基于HTTP长连接传输,仅修改img标签的src或通过*ngIf隐藏元素,浏览器不会主动终止已建立的长连接,导致请求持续运行。以下是两种可行的解决方法:

方法一:通过HttpClient手动控制流订阅

主动管理MJPEG流的HTTP请求,在组件销毁时取消订阅并清理资源:

import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-mjpeg-viewer',
  template: `<img #mjpegImage />`
})
export class MjpegViewerComponent implements OnInit, OnDestroy {
  @ViewChild('mjpegImage') mjpegImage!: ElementRef<HTMLImageElement>;
  private streamSubscription?: Subscription;
  private currentBlobUrl?: string;

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    const mjpegUrl = '你的MJPEG流地址';
    this.streamSubscription = this.http.get(mjpegUrl, {
      responseType: 'blob',
      reportProgress: true
    }).subscribe({
      next: (blob) => {
        // 清理旧的Blob URL避免内存泄漏
        if (this.currentBlobUrl) {
          URL.revokeObjectURL(this.currentBlobUrl);
        }
        this.currentBlobUrl = URL.createObjectURL(blob);
        this.mjpegImage.nativeElement.src = this.currentBlobUrl;
      },
      error: (err) => {
        console.error('MJPEG流加载失败', err);
      }
    });
  }

  ngOnDestroy(): void {
    // 取消订阅,直接终止HTTP请求
    this.streamSubscription?.unsubscribe();
    // 清理Blob URL资源
    if (this.currentBlobUrl) {
      URL.revokeObjectURL(this.currentBlobUrl);
    }
    // 清空img的src
    this.mjpegImage.nativeElement.src = '';
  }
}

方法二:用iframe承载MJPEG流

利用iframe的特性:当元素被移除时,浏览器会自动终止其内部的所有请求:

import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-mjpeg-viewer',
  template: `<div #iframeContainer></div>`
})
export class MjpegViewerComponent implements OnInit, OnDestroy {
  @ViewChild('iframeContainer') iframeContainer!: ElementRef<HTMLDivElement>;
  private iframe?: HTMLIFrameElement;

  ngOnInit(): void {
    const mjpegUrl = '你的MJPEG流地址';
    this.iframe = document.createElement('iframe');
    this.iframe.src = mjpegUrl;
    this.iframe.style.width = '100%';
    this.iframe.style.height = '100%';
    this.iframeContainer.nativeElement.appendChild(this.iframe);
  }

  ngOnDestroy(): void {
    // 移除iframe,立即终止MJPEG流请求
    if (this.iframe) {
      this.iframe.remove();
      this.iframe.src = '';
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 19:32:46