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

Node/Express发送本地PDF至前端后下载空白问题求助

解决Node/Express发送PDF流到前端后下载空白的问题

我来帮你排查这个PDF下载后空白的问题,这种情况基本都是二进制数据的传输、编码处理或者响应头配置出错导致的,咱们一步步拆解解决:

一、先修正服务端路由的核心问题

你提到把PDF转成二进制字符串发送,这是最容易踩的坑——PDF是纯二进制文件,转成字符串再传输会丢失关键的二进制信息,直接用流式传输或者发送Buffer才是正确姿势。

推荐的服务端写法(两种可选)

方式1:用res.sendFile(最简单,Express帮你处理所有细节)

const path = require('path');

app.get('/download-pdf', (req, res) => {
  const pdfFilePath = path.join(__dirname, '你的本地PDF文件路径.pdf');
  
  // 自动设置正确的Content-Type和Content-Disposition
  res.sendFile(pdfFilePath, (err) => {
    if (err) {
      res.status(500).send('读取PDF文件失败');
    }
  });
});

方式2:手动流式传输(适合需要自定义逻辑的场景)

const fs = require('fs');
const path = require('path');

app.get('/download-pdf', (req, res) => {
  const pdfFilePath = path.join(__dirname, '你的本地PDF文件路径.pdf');
  
  // 必须设置的响应头,告诉浏览器这是PDF文件
  res.setHeader('Content-Type', 'application/pdf');
  // 触发下载行为,filename是用户看到的下载文件名
  res.setHeader('Content-Disposition', 'attachment; filename="自定义文件名.pdf"');
  
  // 创建可读流,直接pipe到响应对象,避免手动处理二进制编码
  const pdfStream = fs.createReadStream(pdfFilePath);
  pdfStream.pipe(res);
  
  // 处理流读取错误
  pdfStream.on('error', (err) => {
    console.error('PDF读取错误:', err);
    res.status(500).send('服务器读取PDF失败');
  });
});

⚠️ 重点提醒:绝对不要把PDF转成二进制字符串再发送(比如用fs.readFile的binary编码),这种方式会破坏PDF的二进制结构,导致下载后文件损坏空白。

二、前端接收与下载的正确姿势

前端必须把响应当成二进制Blob对象处理,不能用普通文本/JSON的方式解析,否则会导致数据损坏。

用Fetch API实现下载

fetch('/download-pdf')
  .then(response => {
    if (!response.ok) throw new Error('请求失败');
    return response.blob(); // 关键:获取Blob格式的二进制数据
  })
  .then(blob => {
    // 创建临时下载链接
    const downloadUrl = window.URL.createObjectURL(blob);
    const aTag = document.createElement('a');
    aTag.href = downloadUrl;
    aTag.download = '自定义文件名.pdf'; // 和服务端的filename保持一致也可以
    document.body.appendChild(aTag);
    aTag.click(); // 触发下载
    // 清理临时资源
    window.URL.revokeObjectURL(downloadUrl);
    document.body.removeChild(aTag);
  })
  .catch(err => console.error('下载出错:', err));

用Axios实现下载

axios.get('/download-pdf', {
  responseType: 'blob' // 必须设置这个,告诉Axios返回Blob而非JSON/文本
})
.then(response => {
  const blob = new Blob([response.data], { type: 'application/pdf' });
  const downloadUrl = window.URL.createObjectURL(blob);
  const aTag = document.createElement('a');
  aTag.href = downloadUrl;
  aTag.download = '自定义文件名.pdf';
  document.body.appendChild(aTag);
  aTag.click();
  window.URL.revokeObjectURL(downloadUrl);
  document.body.removeChild(aTag);
})
.catch(err => console.error('下载出错:', err));

三、快速排查你现有代码的问题

  1. 检查服务端响应头:确认是否设置了Content-Type: application/pdf,没有的话浏览器无法识别文件类型,可能导致解析错误。
  2. 检查前端响应类型:如果之前是用response.text()或者默认的JSON解析,立刻改成response.blob()(Fetch)或者设置responseType: 'blob'(Axios)。
  3. 验证数据完整性:在服务端打印PDF文件的大小(fs.statSync(pdfFilePath).size),在前端打印Blob的大小(blob.size),如果两者不一致,说明传输过程中数据丢失,检查服务端流是否被提前终止。

内容的提问来源于stack exchange,提问作者patmedersen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:48:21