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文件损坏,显示乱码。
解决方案
针对单个请求禁用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 }) ); }全局暂时关闭withFetch
如果项目中Blob请求较多,可先在app.config.ts中移除withFetch(),等待Angular后续版本修复该问题后再重新启用。移除reportProgress(可选)
如果不需要下载进度监听,可删除reportProgress: true选项,部分场景下Fetch API能正确处理Blob数据。
内容的提问来源于stack exchange,提问作者Leandro
相关产品推荐
相关产品推荐

