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

Node后端向客户端传输PDF时出现空白页问题

这个问题的核心是前端错误地将二进制PDF数据转换成了文本字符串,同时后端和网关的一些设置也需要调整,最终导致下载的PDF文件结构损坏。咱们一步步来修复:

1. 前端代码修复(最关键的问题)

你现在用response.text()来处理PDF响应,这会把二进制数据强制解码成UTF-8字符串——但PDF是纯二进制格式,这个过程会破坏原始字节结构:比如一些无法用UTF-8表示的字节会被替换成占位符,再转成Blob时就完全不是原来的文件了。

修改前端代码:

  • 把response.text()换成response.blob(),直接获取二进制Blob对象;
  • 不需要手动创建Blob,直接用返回的blob生成ObjectURL即可。

修改后的代码:

// 修正retrievePDF函数
function retrievePDF () {
  return fetch('backendurlhere', {
    method: 'GET',
    // GET请求不需要设置Content-Type请求头,服务器会返回正确的类型
    credentials: 'include'
  })
  .then(response => response.blob()) // 直接获取二进制Blob
  .catch(err => console.log('ERR', err))
}

// 修正React组件中的generatePDF方法
generatePDF () {
  this.props.retrievePDF()
  .then(pdfBlob => {
    const objectUrl = window.URL.createObjectURL(pdfBlob)
    window.open(objectUrl)
  })
}

2. Node后端(Restify)代码修复

你在createReadStream里设置了encoding: 'binary',这会让流输出的是字符串而非原始Buffer。Restify处理二进制时,直接用原始Buffer流即可,不需要指定编码。

修改后端代码:

export async function generatePDF (req, res, next) {
  try {
    // 移除encoding: 'binary',让流输出原始二进制Buffer
    const fStream = fs.createReadStream(path.join(__dirname, 'businesscard.pdf'))
    // 明确设置Content-Type为PDF
    res.setHeader('Content-Type', 'application/pdf')
    // 使用Restify的sendRaw方法直接传输二进制流,避免额外编码转换
    res.sendRaw(fStream)
    next()
  } catch (err) {
    res.send(err)
    next()
  }
}

注:Restify的send()会自动处理编码逻辑,而sendRaw()更适合直接传输二进制数据,避免不必要的转换。

3. API网关设置修复

从你的HTTP响应头看到Content-Type: application/octet-stream,但网关应该明确设置为application/pdf,这样浏览器才能正确识别文件类型。确保网关要么保留后端返回的Content-Type,要么手动设置为application/pdf,不要替换成octet-stream。

另外,检查网关是否自动添加了Content-Encoding: gzip——如果后端没有对PDF做gzip压缩,网关的自动压缩可能会导致二进制数据损坏(虽然gzip本身合法,但最好由后端控制压缩逻辑)。

为什么之前的尝试无效?

你用readFileSync或手动拼接Buffer返回的方式没问题,但前端依然用response.text()处理,还是会把二进制转成字符串破坏结构。只有前端正确获取二进制Blob,才能保证文件完整。

验证修复效果

修复后,下载的PDF文件大小应该和原文件完全一致,用验证工具检测也不会再出现xref表损坏、Flate流错误等问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:38:59