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

Angular 17启用withFetch后BLOB类型PDF加载异常排查

问题描述

在Angular 17中启用withFetch后,原本正常的BLOB类型GET接口出现异常:PDF文件无法在iframe中正常加载,显示乱码文本;但关闭withFetch后PDF可正常显示。编译及运行阶段均无报错。

相关代码

app.config.ts

export const appConfig: ApplicationConfig = {
    providers: [
        provideRouter(routes),
        provideHttpClient(
            withInterceptorsFromDi(),
            withFetch()
        ),   
        // 其他提供者
    ]
}

services.ts

public downloadDiagrammedPdf(sumarioId: number, nomeDoDiagramaPDF: string): Observable<HttpEvent<Blob>> {
    return this.http.request(
      new HttpRequest('GET', `${this.apiDownloadPdfUrl}?sumarioId=${sumarioId}&nomeDoDiagramaPDF=${nomeDoDiagramaPDF}`, null, {
        reportProgress: true,
        responseType: 'blob',
      })
    );
  }

showPdf.component.ts

downloadFile(sumarioId: number, nomeDoDiagramaPDF: string): void {
    this.serviceUpDown.downloadDiagrammedPdf(sumarioId, nomeDoDiagramaPDF).subscribe({
      next: (data) => {
        switch (data.type) {
          case HttpEventType.DownloadProgress:
            break;
          case HttpEventType.Response:
            const file = new Blob([data.body as BlobPart], {
              type: data.body?.type,
            });
            this.createPdfFromBlob(file);
            break;
        }
      },
      error: (err) => {
        if (err.status == 404) {
          this.router.navigate(['app-error-page']);
        } else {
          console.log(err);
        }
      },
      complete: () => { }
    });
  }

  createPdfFromBlob(file: Blob) {
    this.pdfSrc = this.sanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(file));
  }

依赖版本

{
    "@angular/animations": "^17.0.2",
    "@angular/cdk": "^17.0.0",
    "@angular/common": "^17.0.2",
    "@angular/compiler": "^17.0.2",
    "@angular/core": "^17.0.2",
    "@angular/forms": "^17.0.2",
    "@angular/material": "^17.0.0",
    "@angular/platform-browser": "^17.0.2",
    "@angular/platform-browser-dynamic": "^17.0.2",
    "@angular/platform-server": "^17.0.2",
    "@angular/router": "^17.0.2",
    "@angular/ssr": "^17.0.0",
    "@auth0/angular-jwt": "^5.1.2",
    "@material/icon-button": "^15.0.0-canary.684e33d25.0",
    "angular-imask": "^7.1.3",
    "express": "^4.15.2",
    "ngx-toastr": "^17.0.2",
    "rxjs": "~7.8.1",
    "tslib": "^2.6.2",
    "zone.js": "~0.14.2"
  }
问题分析与解决

这是Angular 17引入withFetch后的已知兼容性问题,根源在于Fetch API处理responseType: 'blob'并启用reportProgress时,和传统XHR的数据流处理逻辑不一致,导致Blob数据被错误地以文本编码解析,最终生成的PDF文件损坏,显示乱码。

解决方案

  1. 针对单个请求禁用Fetch
    在请求选项中添加HttpContext,强制该请求使用XHR而非Fetch,不影响全局配置:

    import { HttpContext, HttpRequest } from '@angular/common/http';
    import { USE_FETCH } from '@angular/common/http/src/client/fetch';
    
    public downloadDiagrammedPdf(sumarioId: number, nomeDoDiagramaPDF: string): Observable<HttpEvent<Blob>> {
        return this.http.request(
          new HttpRequest('GET', `${this.apiDownloadPdfUrl}?sumarioId=${sumarioId}&nomeDoDiagramaPDF=${nomeDoDiagramaPDF}`, null, {
            reportProgress: true,
            responseType: 'blob',
            context: new HttpContext().set(USE_FETCH, false) // 禁用Fetch,使用XHR
          })
        );
      }
    
  2. 全局暂时关闭withFetch
    如果项目中Blob请求较多,可先在app.config.ts中移除withFetch(),等待Angular后续版本修复该问题后再重新启用。

  3. 移除reportProgress(可选)
    如果不需要下载进度监听,可删除reportProgress: true选项,部分场景下Fetch API能正确处理Blob数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:45:01