后端返回PDF下载后显示空白页问题排查求助
下载PDF空白问题排查与解决
问题描述
处理后端发送的PDF下载时,获取Blob响应后,下载的PDF页数和预期一致,但所有页面都是空白。发现后端返回的PDF用记事本打开显示为UTF-8格式,而本地正常PDF显示为ANSI格式,需要确认是否是编码或代码问题。
相关截图
后端响应预览

请求头与数据详情

空白PDF页面效果

记事本打开的PDF内容

相关代码
前端下载代码
const receipt = await this.downloadBookingReceipt({ bookingNumber: this.bus.bookingReference, receiptFormat: 'pdf', }); /** * 使用 file-saver 库 */ const blob = new Blob([receipt.data], { type: 'application/pdf' }); saveAs(blob, 'receipt.pdf', { autoBom: true }); /** * 使用 <a> 标签 */ const pdfData = new Blob([receipt], { type: 'application/pdf' }); // 创建指向Blob对象URL的链接 const pdfUrl = window.URL.createObjectURL(pdfData); const downloadLink = document.createElement('a'); downloadLink.href = pdfUrl; downloadLink.download = `${this.bus.bookingReference}-receipt.pdf`; downloadLink.click(); setTimeout(function () { // Firefox需要延迟撤销ObjectURL window.URL.revokeObjectURL(pdfUrl); }, 100);
downloadBookingReceipt 请求函数
static async downloadBookingReceipt (axios, { bookingNumber, receiptFormat }) { return await axios.get( `/v1/booking/${bookingNumber}/receipt/${receiptFormat}`, { responseType: 'blob', } ); }
后端接口处理代码
/** * 预订收据处理逻辑 */ const { data } = await axios.get(BASE_URL + req._parsedUrl.path, { headers: { AccessToken: TOKEN, }, }); res.setHeader( 'content-disposition', `attachment; filename="${req.url.slice(9, 18)}-receipt.pdf"` ); res.setHeader('Content-Type', 'application/pdf'); res.end(data); /** */
问题原因与修复方案
核心问题
后端转发第三方PDF接口时,未指定响应类型为二进制流,导致axios默认把返回的PDF二进制数据解析成了UTF-8编码的字符串。后续转成Blob时,原始二进制内容被损坏,最终打开的PDF就是空白页。
修复步骤
- 后端修改:调用第三方接口时添加
responseType: 'arraybuffer',确保拿到原始二进制数据:
const { data } = await axios.get(BASE_URL + req._parsedUrl.path, { headers: { AccessToken: TOKEN, }, responseType: 'arraybuffer' // 新增该行 });
这样后端获取的data是二进制数组,而非UTF-8字符串,转发给前端时不会损坏内容。
- 前端优化:
<a>标签下载的代码中,错误地将整个receipt响应对象传入Blob,要和file-saver写法一致,使用receipt.data:// 原错误代码 const pdfData = new Blob([receipt], { type: 'application/pdf' }); // 修正后 const pdfData = new Blob([receipt.data], { type: 'application/pdf' });- PDF是二进制文件,不需要开启
autoBom: true,建议移除该选项避免自动添加BOM头损坏文件:saveAs(blob, 'receipt.pdf'); // 移除autoBom参数
编码说明
PDF本身是二进制格式,不存在UTF-8或ANSI的说法。记事本显示的编码差异,是因为它把损坏的二进制内容当成文本解析时的编码猜测,核心问题还是二进制数据被错误转换成了字符串。
内容的提问来源于stack exchange,提问作者DarkPo13
相关产品推荐
相关产品推荐

