ng2-pdf-viewer渲染内存Blob PDF触发二次请求报403如何解决
ng2-pdf-viewer渲染内存Blob格式PDF触发额外403请求问题
问题现象
- 使用ng2-pdf-viewer渲染已存储在内存中的Blob格式PDF时持续返回403错误
- 存储Blob的变量可直接用于本地文件下载,功能运行正常,但PDF渲染始终失败
- 问题仅出现在开发服务器环境,本地localhost运行时所有功能无异常
- 经排查:即使
[src]属性绑定的是内存中的Blob变量,ng2-pdf-viewer渲染时仍会额外向后端发起二次请求,该请求直接触发403错误
事件复现链路
- 调用后端接口加载PDF文件,在subscribe回调中将返回的PDF Blob赋值给
file变量 isFilePdF()判断结果为真后,*ngIf触发pdf-viewer组件开始渲染- 组件渲染阶段自动发起额外后端请求导致403报错,业务代码中无对应二次请求逻辑
相关代码片段
TypeScript 实现
downloadFile(observable: Observable<any>) { observable.subscribe((document: any) => { console.log(document) this.file = document; console.log(this.file) if (!this.isFilePdF()) { this.isLoading = false; } }) }
HTML 模板实现
<pdf-viewer (error)="logError($event)" [zoom]="zoomRatio" [hidden]="isLoading" *ngIf="isFilePdF()" (after-load-complete)="finishLoading($event)" [(page)]="currentPage" [src]="file" [original-size]="false" [class.height]="!isLoading" style="width: 100%; background-color:whitesmoke"> </pdf-viewer>
报错表现
首次文件下载请求状态正常,无业务逻辑触发的二次请求返回403状态码。
解决方案
核心原因:ng2-pdf-viewer默认对传入的原始Blob值未做正确的源类型识别,会尝试将其解析为远程URL地址发起请求,才会出现无业务逻辑的二次后端调用。手动将Blob转为组件可识别的本地Blob URL再传入即可解决问题:
- 拿到接口返回的Blob对象后,不要直接赋值给绑定的
file变量,先调用URL.createObjectURL()生成内存本地URL
调整后的TypeScript代码如下:downloadFile(observable: Observable<any>) { observable.subscribe((document: Blob) => { // 生成本地Blob URL,截断组件向外发起请求的逻辑 this.file = URL.createObjectURL(document); if (!this.isFilePdF()) { this.isLoading = false; } }) } - 做好内存管理,在组件销毁、PDF文档切换的时机,调用
URL.revokeObjectURL(this.file)释放已生成的Blob URL,避免内存泄漏 - 做类型兼容校验:如果仍有异常,确认接口返回的Blob对象
type属性为application/pdf,若后端返回未带正确类型,可在生成Blob时手动指定:const pdfBlob = new Blob([document], { type: 'application/pdf' }); this.file = URL.createObjectURL(pdfBlob);
该方案可完全拦截组件的额外后端请求,直接读取本地内存中的PDF文件完成渲染,开发环境、生产环境均可正常运行,不影响原有本地下载功能。
内容的提问来源于stack exchange,提问作者Cingen
相关产品推荐
相关产品推荐

