React前端无法下载Puppeteer生成的PDF,下载后文件为空
如何在React前端正确下载Puppeteer生成的PDF?
问题描述
后端使用Puppeteer生成PDF,前端收到的响应数据格式如下:
%PDF-1.4 %���� 1 0 obj <<Creator (Chromium) /Producer (Skia/PDF m117) /CreationDate (D:20231030121554+00'00') /ModDate (D:20231030121554+00'00')>> endobj 3 0 obj <<ca 1 /BM /Normal>> endobj 4 0 obj <<ca .0314/Filter /FlateDecode /Length 4339>> stream x��[�۸��g<�O�@�/�}���@Q�(�`�)Y3{�bg�t������l�-�� t3W��)���(�J���%��@G@��Ն�.a�p��i�/
尝试了两种前端下载代码,均无效,下载后得到空PDF(后端确认生成的PDF正常):
第一种代码:
const arr = new Uint8Array(response?.data); const blob = new Blob([arr], { type: 'application/pdf' }); // const blob = new Blob([response], { type: 'application/pdf' }); // Create a URL for the Blob const url = URL.createObjectURL(blob); // Create a download link const a = document.createElement('a'); a.href = url; a.download = 'example.pdf'; // Specify the filename for the download a.style.display = 'none'; // Add the link to the DOM and trigger a click event document.body.appendChild(a); a.click(); // Clean up by removing the link and revoking the URL document.body.removeChild(a); URL.revokeObjectURL(url);
第二种代码:
const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', fileName); document.body.appendChild(link); link.click();
解决步骤
1. 请求时指定二进制响应类型
核心问题是前端默认会把响应解析为UTF-8字符串,导致PDF二进制数据损坏。必须在请求接口时设置responseType为blob或arraybuffer。
Axios示例:
import axios from 'axios'; const downloadPDF = async () => { try { const response = await axios.get('/api/generate-pdf', { responseType: 'blob' // 关键配置:获取Blob格式的二进制数据 }); // 生成下载链接并触发下载 const url = URL.createObjectURL(response.data); const a = document.createElement('a'); a.href = url; a.download = 'example.pdf'; document.body.appendChild(a); a.click(); // 清理资源 document.body.removeChild(a); URL.revokeObjectURL(url); } catch (error) { console.error('PDF下载失败:', error); } };
原生Fetch示例:
const downloadPDF = async () => { try { const response = await fetch('/api/generate-pdf'); const blob = await response.blob(); // 直接将响应转为Blob const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'example.pdf'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } catch (error) { console.error('PDF下载失败:', error); } };
2. 验证数据转换正确性
如果使用responseType: 'arraybuffer',需要先将ArrayBuffer转为Blob再生成下载链接:
const blob = new Blob([response.data], { type: 'application/pdf' });
3. 确认后端响应头
后端返回PDF时,需确保响应头包含以下字段,帮助浏览器正确识别文件类型:
Content-Type: application/pdf Content-Disposition: attachment; filename="example.pdf"
内容的提问来源于stack exchange,提问作者Waqas Khan
相关产品推荐
相关产品推荐

