node.js - 从 Node 读取 pdf 并将其发送到客户端 - 空白页

标签 node.js pdf encoding blob restify

我目前正在通过 Node 后端读取 PDF,通过 API 网关层将其发送回客户端 - 然而,当响应到达客户端时,会以正确的页数下载 pdf,但完全是空白的。我尝试过多种方式设置编码,但没有成功。将编码设置为二进制并运行下载的 PDF 与原始 PDF 的差异时,即使文件大小不同,也没有明显的差异。

Node 后端: `

export async function generatePDF (req, res, next) {
  try {
    const fStream = fs.createReadStream(path.join(__dirname, 'businesscard.pdf'), { encoding: 'binary' }) // have also tried without the binary encoding
    return fStream.pipe(res)
  } catch (err) {
    res.send(err)
  }
}

`

API 网关只需向 Node 后端发送请求并在发送之前设置内容类型: `

res.setHeader('Content-Type', 'application/pdf')

`

前端: `

function retrievePDF () {
  return fetch('backendurlhere', {
    method: 'GET',
    headers: { 'Content-Type': 'application/pdf' },
    credentials: 'include'
  })
    .then(response => {
      return response.text()
    })
    .catch(err => {
      console.log('ERR', err)
  })

`

retrievePDF 被调用,然后通过 React 组件执行以下操作: `

  generatePDF () {
    this.props.retrievePDF()
      .then(pdfString => {
        const blob = new Blob([pdfString], { type: 'application/pdf' })
        const objectUrl = window.URL.createObjectURL(blob)
        window.open(objectUrl)
      })
  }

`

响应的字符串表示形式看起来有点像这样(只是一个示例): `

%PDF-1.4
1 0 obj
<<
/Title (þÿ)
/Creator (þÿ)
/Producer (þÿQt 5.5.1)
/CreationDate (D:20171003224921)
>>
endobj
2 0 obj
<<
/Type /Catalog
/Pages 3 0 R
>>
endobj
4 0 obj
<<
/Type /ExtGState
/SA true
/SM 0.02
/ca 1.0
/CA 1.0
/AIS false
/SMask /None>>
endobj
5 0 obj
[/Pattern /DeviceRGB]
endobj
6 0 obj
<<
/Type /Page
/Parent 3 0 R
/Contents 8 0 R
/Resources 10 0 R
/Annots 11 0 R
/MediaBox [0 0 142 256]
>>
endobj
10 0 obj
<<
/ColorSpace <<
/PCSp 5 0 R
/CSp /DeviceRGB
/CSpg /DeviceGray
>>
/ExtGState <<
/GSa 4 0 R
>>
/Pattern <<
>>
/Font <<
/F7 7 0 R
>>
/XObject <<
>>
>>
endobj
11 0 obj
[ ]
endobj
8 0 obj
<<
/Length 9 0 R
/Filter /FlateDecode
>>
stream
xåW]kÂ0}ϯ¸ÏÕ$mÆ`V6{{ºÊûûKÓ´vS¥N_f°WsÒ{ÏýÈMÛ»<ÑëzÙä¦Af&»q^©4MlE+6fcw-äUwp?ÖÓ%ëºX93Éî/tã¾·næ5Å¢trîeaiÎx-ù7vFËCí5nl¢¸Myláïmå·Ïgö²G±T  ¹ïÒZk¢ð£¹¼)<äµµwm7ösÖ2¿P#¥ryëþèò]pÎÅ%åïÌDRqÿ)ôHTxpÄQOtjTI"ØBGd¤º
¢=¢£8Ú¶c¢téÑIþ¶c¡¶æ.ÇK»¾
ä¥.Inþ)(ÚbX¹Mqs«b²5B¡vÚ ò·ÚNeçmÇ.![¨±87¿ÜÂõ[H ¢à>ëRÄ]ZNæÚÂú¿·PWÒU4¢ØR]Ê®Kj±6\\ÐNØFG¬Ô;ÝRLüݱP[>·~'½%ä8M8丸0ýiiÕ}ت³S$=N*s'>¹³§VùGfûÉU`ËÁ¥wú®FéC^½"òºBcö
Ùå@endstream
endobj

`

HTTP 响应如下所示: `

access-control-allow-credentials: true
access-control-allow-origin: http://frontend.dev.com
access-control-expose-headers: api-version, content-length, content-md5, content-type, date, request-id, response-time
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/octet-stream
Date: Wed, 09 May 2018 09:37:22 GMT
Server: nginx/1.13.3
Transfer-Encoding: chunked
vary: origin

`

我还尝试了其他读取文件的方法,例如 readFileSync,以及通过 fStream.on('data') 构造 block 并作为缓冲区发送回来。似乎没有任何作用。

注意:我正在使用 Restify(不是 Express)

编辑: 通过验证器运行文件显示以下内容: `

File    teststring.pdf
Compliance  pdf1.4
Result  Document does not conform to PDF/A.
Details 
Validating file "teststring.pdf" for conformance level pdf1.4

The 'xref' keyword was not found or the xref table is malformed.

The file trailer dictionary is missing or invalid.

The "Length" key of the stream object is wrong.

Error in Flate stream: data error.

The "Length" key of the stream object is wrong.

Error in Flate stream: data error.

The document does not conform to the requested standard.

The file format (header, trailer, objects, xref, streams) is corrupted.

The document does not conform to the PDF 1.4 standard.

Done.

`

最佳答案

对于任何有问题的人,我发现在我的网关层中,请求被包装在一个实用程序函数中,该函数对响应执行文本读取,即

return response.text()

我删除了它,而是通过管道传输来自后端的响应:

fetch('backendurl') .then(({ body }) => { body.pipe(res) })

希望这可以帮助任何使用网关模式并遇到类似问题的人

关于node.js - 从 Node 读取 pdf 并将其发送到客户端 - 空白页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50250440/

相关文章:

node.js - Ionic 5.4.16 无法在 Node 12.19.0 @ Ubuntu 20.04 上运行

javascript - 在 Node 中抓取 .aspx 页面

php - FPDF + 关联数组键值列

javascript - Webpack 不注入(inject)变量

java - 使用 Java 将 PDF(1.4 和 1.5)可靠地打印到网络打印机

javascript - 如何将 JavaScript 代码放入 PDF 文档?

java - Java编码

java - Java 邮件中的 URL 编码

字符编码 C 和瑞典语 åöä

javascript - Meteor:按文本属性删除不起作用