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

Koa应用获取远程PDF返回空白页的问题排查及解决方案

解决Koa接口返回空白PDF的问题

我来帮你搞定这个问题!你遇到的空白PDF问题,大概率是因为请求远程PDF时没有正确处理二进制数据,或者响应头转发出了问题。下面是具体的排查和解决方案:

核心原因:二进制数据被错误解析

request 模块默认会把响应内容解析为UTF-8字符串,而PDF是二进制文件,转成字符串再转回Buffer的过程中会丢失关键字节,导致文件损坏显示空白。

解决方案1:设置encoding: null获取原始二进制数据

修改你的代码,在请求时指定encoding: null,让request返回原始的Buffer而非字符串:

router.get('/pdf', function *() { 
  const url = 'http://example.com/pdf' 
  // 关键:设置encoding为null,确保获取二进制Buffer
  const res = yield request({ url, encoding: null }) 
  
  this.status = res.statusCode 
  
  // 只转发必要的响应头,避免冲突(比如Transfer-Encoding这类和当前请求绑定的头)
  const safeHeaders = ['Content-Type', 'Content-Length', 'Content-Disposition']
  safeHeaders.forEach(header => {
    if (res.headers[header.toLowerCase()]) {
      this.set(header, res.headers[header.toLowerCase()])
    }
  })
  
  this.body = res.body 
})

额外注意事项

  1. 强制指定Content-Type
    有时候远程服务器返回的Content-Type可能不正确,或者被中间件篡改,你可以手动设置确保客户端能识别PDF:

    this.set('Content-Type', 'application/pdf')
    
  2. 处理流式响应
    如果远程服务器用分块传输(Transfer-Encoding: chunked),直接返回Buffer可能不如流式传输可靠,这时候可以用管道(pipe)把远程响应流直接传给Koa的响应:

    router.get('/pdf', function *() { 
      const url = 'http://example.com/pdf' 
      const res = request({ url, encoding: null }) // 这里不用yield,直接获取流
      
      this.status = res.statusCode 
      this.set('Content-Type', 'application/pdf')
      
      // 把远程响应流pipe到Koa的response对象
      res.pipe(this.res)
      
      // 等待流传输完成
      yield new Promise((resolve) => res.on('end', resolve))
    })
    
  3. 避免转发所有响应头
    不要盲目转发res.headers里的所有字段,比如Connection、Transfer-Encoding这些头是和当前HTTP连接绑定的,转发给客户端会导致解析错误,只保留和文件内容相关的头即可。

按照上面的方法修改后,应该就能正常返回有内容的PDF了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:21:57