如何将通过Axios从WordPress REST API获取的PDF原始数据在iframe或PDF.js中展示?
解决PWA中离线存储并展示PDF的问题
嗨,我来帮你搞定这个问题~你现在用Axios拿到的是PDF原始文本,核心原因是Axios默认会把响应解析成JSON格式,咱们只需要调整一下请求的响应类型,再把数据转换成合适的格式,就能在iframe或者PDF.js里正常展示了。
第一步:修改Axios请求的响应类型
首先,在你的getPDFTest方法里,给Axios的get请求加上responseType配置,指定为'blob'(或者'arraybuffer',两种格式后续都能适配展示需求):
async getPDFTest() { if (typeof indexedDB === 'undefined') { this.supported = false; return; } try { const response = await axios.get('https://staging-nasapi.kinsta.cloud/wp-content/uploads/2021/08/Transitions-PG_E.pdf', { responseType: 'blob' // 关键配置:告诉Axios返回Blob类型数据 }); // 这里调用展示PDF的方法,二选一即可 this.displayPDFInIframe(response.data); // this.displayPDFWithPDFJS(response.data); } catch (error) { console.log('Error getting offline PDF', error); } },
方式一:在iframe中快速展示PDF
拿到Blob数据后,我们可以创建一个临时的Blob URL,把它赋值给iframe的src属性就能直接渲染PDF了,这是最简单的展示方式:
displayPDFInIframe(blob) { // 创建临时Blob URL const pdfUrl = URL.createObjectURL(blob); // 获取页面上的iframe元素(假设你有一个id为pdf-iframe的iframe标签) const iframe = document.getElementById('pdf-iframe'); iframe.src = pdfUrl; // 记得在iframe加载完成后清理Blob URL,避免内存泄漏 iframe.onload = () => { URL.revokeObjectURL(pdfUrl); }; }
方式二:用PDF.js自定义展示(更灵活)
如果需要更灵活的控制(比如自定义分页、缩放、添加交互),推荐用PDF.js来渲染。我们可以把Blob转换成Uint8Array,再传给PDF.js的核心方法:
displayPDFWithPDFJS(blob) { // 把Blob转换成ArrayBuffer,再转成PDF.js需要的Uint8Array格式 blob.arrayBuffer().then((arrayBuffer) => { const pdfData = new Uint8Array(arrayBuffer); // 初始化PDF文档 pdfjsLib.getDocument({ data: pdfData }).promise.then((pdf) => { console.log('PDF加载成功,总页数:', pdf.numPages); // 先渲染第一页示例 this.renderPDFPage(pdf, 1); }); }); }, renderPDFPage(pdf, pageNum) { pdf.getPage(pageNum).then((page) => { const canvas = document.getElementById('pdf-canvas'); const ctx = canvas.getContext('2d'); // 设置页面缩放比例 const viewport = page.getViewport({ scale: 1.5 }); // 调整canvas尺寸匹配PDF页面 canvas.height = viewport.height; canvas.width = viewport.width; // 把PDF页面渲染到canvas上 page.render({ canvasContext: ctx, viewport: viewport }); }); }
注意:使用PDF.js需要先在项目中引入它的库文件(可以通过npm安装或者本地添加脚本),这里就不提供外链啦,你直接在项目中添加依赖即可。
后续离线存储扩展
如果之后要实现离线存储,你可以把Blob数据或者ArrayBuffer直接存入IndexedDB,下次离线时从IndexedDB取出数据,再用上面的任意一种方法展示就可以啦~
内容的提问来源于stack exchange,提问作者Connavear
相关产品推荐
相关产品推荐

