Angular 5应用中PDF文件流渲染的问题与解决方案
Angular 5 处理PDF文件流并渲染的解决方案
问题1:请求返回200但触发错误分支
你遇到的问题核心在于Angular的HttpClient默认会把响应解析为JSON格式,但你请求的是二进制PDF流,所以即便服务器返回200状态码,客户端也会因为解析失败触发错误分支。
解决起来很简单,只需要在HttpClient.get()的配置选项里指定responseType为'blob'或'arraybuffer',明确告诉Angular不要尝试把响应解析成JSON。修改你的服务方法如下:
public getPdfFileStream(caseId: string) { const url = `${this.CASE_API_URL}/${caseId}/pdf`; const headers = new HttpHeaders().set('Accept', 'application/pdf'); return this.httpClient.get(url, { headers: headers, responseType: 'blob' // 指定响应类型为二进制Blob }); }
如果更习惯处理二进制数组,也可以替换成responseType: 'arraybuffer',后续渲染时的转换逻辑类似。
问题2:解析并渲染PDF
结合你提到的ng2-pdf-viewer库,这里提供两种实用的渲染方案:
方案1:通过Blob URL在新窗口打开预览
如果只需要快速打开PDF查看,可以把获取到的Blob转换为本地临时URL,再通过window.open()打开:
fetchPdfAjaxRequest(caseId: string) { this.caseListService.getPdfFileStream(caseId) .takeUntil(this.ngUnsubscribe) .subscribe( (pdfBlob: Blob) => { const fileURL = URL.createObjectURL(pdfBlob); window.open(fileURL); // 记得在合适时机释放URL资源,避免内存泄漏 // setTimeout(() => URL.revokeObjectURL(fileURL), 10000); }, (error) => { this.errorService.displayError(error.status, error.statusText); } ); }
方案2:使用ng2-pdf-viewer在页面内嵌入渲染
如果需要把PDF直接嵌入到页面中,ng2-pdf-viewer支持直接传入Blob或Uint8Array作为src。如果服务返回的是arraybuffer类型,先转换成Uint8Array即可:
// 假设服务中使用responseType: 'arraybuffer' fetchPdfAjaxRequest(caseId: string) { this.caseListService.getPdfFileStream(caseId) .takeUntil(this.ngUnsubscribe) .subscribe( (pdfBuffer: ArrayBuffer) => { this.pdfData = new Uint8Array(pdfBuffer); }, (error) => { this.errorService.displayError(error.status, error.statusText); } ); }
然后在模板中调用组件:
<pdf-viewer [src]="pdfData" [render-text]="true" style="display: block;"></pdf-viewer>
如果服务返回的是Blob类型,直接把Blob对象赋值给src即可,组件会自动处理解析。
@更新:第一个问题已由@Zlatko解决,上述渲染PDF的方案已验证可行。
内容的提问来源于stack exchange,提问作者dave0688
相关产品推荐
相关产品推荐

