Angular 9中替代弃用API,在新标签页打开Blob格式PDF
解决Angular 9中Blob格式PDF在新标签页打开的问题
首先得纠正一个误解:window.URL.createObjectURL(blob) 并没有被弃用——被弃用的是它用于MediaStream的场景,处理Blob时完全可以正常使用。你遇到的报错,核心原因是你直接把Observable赋值给了blob变量,而没有订阅获取实际的Blob数据,因为你的getPdfReport方法返回的是Observable<Blob>,不是同步的Blob对象。
接下来给你调整后的完整代码:
1. 修正组件中的downloadFile方法(改为打开新标签页而非下载)
downloadFile() { console.log('File download started.'); // 订阅Observable获取Blob数据 this.agreementService.getPdfReport(this.agreementNumber).subscribe({ next: (blob) => { // 创建Blob的URL const url = window.URL.createObjectURL(blob); // 在新标签页打开PDF const newTab = window.open(url, '_blank'); // 可选:标签页加载完成后释放URL对象,避免内存泄漏 if (newTab) { newTab.onload = () => { window.URL.revokeObjectURL(url); }; } }, error: (err) => { console.error('Failed to fetch PDF:', err); // 这里可以添加错误提示逻辑,比如弹出提示框 } }); }
2. 优化Service中的方法写法
你的getPdfReport方法逻辑没问题,这里可以优化一下HttpHeaders的写法,同时明确返回类型:
getPdfReport(agreementNumber: string): Observable<Blob> { this.requestUrl = `${configs.api}v1/reports/${agreementNumber}/Agreement.pdf`; const headers = new HttpHeaders().set('Accept', 'application/pdf'); // 加`as 'json'`是为了绕过TypeScript的类型检查,属于Angular处理Blob的常见技巧 return this.http.get<Blob>(this.requestUrl, { headers, responseType: 'blob' as 'json' }); }
额外说明:关于“替代createObjectURL”的误区
如果你确实想避免使用createObjectURL,也可以用FileReader将Blob转换为Data URL,不过对于大文件来说,createObjectURL的性能更好(不需要把整个文件加载到内存)。用FileReader的示例代码如下:
this.agreementService.getPdfReport(this.agreementNumber).subscribe({ next: (blob) => { const reader = new FileReader(); reader.onload = () => { window.open(reader.result as string, '_blank'); }; reader.readAsDataURL(blob); } });
总结一下,你之前的报错和“弃用”无关,是因为没有正确订阅Observable拿到Blob数据。按照上面的代码调整后,就能正常在新标签页打开PDF了。
内容的提问来源于stack exchange,提问作者developer1
相关产品推荐
相关产品推荐

