You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:27:36