【问题标题】:How to send PDF file to frontend?如何将PDF文件发送到前端?
【发布时间】:2018-08-14 20:47:42
【问题描述】:

我的系统上有一个保存的 .PDF 文件,我正在尝试使用 node/express 将该文件发送到前端。

我将文件作为流(二进制字符串)发送到前端,但是当在前端运行一些代码以将 .PDF 下载到用户计算机上时,.PDF 文件显示为空白。

这是我在服务器上的路线:

app.post('/someroute', (req, res) => {
  let pdfPath = './somepath/where/the/pdf/is'
  // if the file does not exist
  if (!fs.existsSync(pdfPath)) {
    console.log(`The PDF does NOT exist @ ${pdfPath}`)
    return res.json({ success: false });
  }

  res.download(pdfPath, (err) => {
    if (err) {
      console.log('there was error in res.downoad!', err)
    } else {
      fs.unlink(pdfPath, (err) => {
        if (err) {
          console.log('there was error in unlinking the pdf file!', err)
        } else {
          console.log('success!')
        }
      })
    }
  })
})

这是前端的代码:

$.post("/someroute", function(data) {
    console.log('creating PDF...', data)

    var downloadLink = document.createElement('a')
    downloadLink.target = '_blank'
    downloadLink.download = 'new_pdf_haha.pdf'
    var blob = new Blob([data], { type: 'application/pdf' })
    var URL = window.URL || window.webkitURL
    var downloadUrl = URL.createObjectURL(blob)
    // set object URL as the anchor's href
    downloadLink.href = downloadUrl
    // append the anchor to document body
    document.body.append(downloadLink)
    // fire a click event on the anchor
    downloadLink.click()
    // cleanup: remove element and revoke object URL
    document.body.removeChild(downloadLink)
    URL.revokeObjectURL(downloadUrl)
  })

这是我在前端收到的流: stream on the frontend

这是我希望在前端下载的 PDF:

以下是实际下载的内容:

如果有人可以提供任何见解或帮助,将不胜感激,谢谢!

【问题讨论】:

    标签: javascript node.js express pdf


    【解决方案1】:

    我认为这对您不起作用的主要原因是 jQuery 不支持“blob”数据类型。

    我做了一些研究,发现了一个如何让它与 jQuery 一起工作的示例:

    http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/

    您需要包含博客文章中的 jQuery 插件,然后将您的 $.post 调用转换为 $.ajax 调用(使用 POST 方法)并指定传输数据类型为“二进制”(以加载插件)。

    包含插件后,将代码更改为如下所示:

        $.ajax({
                method: "POST",
                url: "/someroute",
                dataType: 'binary' // USE THE PLUGIN
            })
            .then(function (data) {
                console.log("Got the PDF file!");
    
                // Do with the PDF data as you please.
    
                var downloadLink = document.createElement('a')
                downloadLink.target = '_blank'
                downloadLink.download = 'new_pdf_haha.pdf'
                var blob = new Blob([data], { type: 'application/pdf' })
                var URL = window.URL || window.webkitURL
                var downloadUrl = URL.createObjectURL(blob)
                downloadLink.href = downloadUrl
                document.body.append(downloadLink) // THIS LINE ISN'T NECESSARY
                downloadLink.click()
                document.body.removeChild(downloadLink);  // THIS LINE ISN'T NECESSARY
                URL.revokeObjectURL(downloadUrl);
            })
            .catch(function (err) {
                console.error("An error occurred.");
                console.error(err);
            });
    

    这里有一个完整的工作示例:

    https://github.com/ashleydavis/pdf-server-example

    请注意,我的服务器设置与您的不同,这对您来说可能是也可能不是问题。我已经包含了用于比较流式和非流式 PDF 文件下载的示例代码 - 默认使用流式传输,因为我认为这就是您想要的。

    另请注意,似乎没有必要将您的合成链接添加到文档中,我已将这些行标记为不必要。

    我还应该注意,最好使用 HTTP GET 而不是 HTTP POST 来做这种事情。如果你这样做了,你可以将你的浏览器下载代码简化为如下:

            var downloadLink = document.createElement('a');
            downloadLink.target = '_blank';
            downloadLink.download = 'new_pdf_haha.pdf';
            downloadLink.href = "someroute";
            document.body.append(downloadLink)
            downloadLink.click()
            document.body.removeChild(downloadLink);
    

    【讨论】:

    • 不客气。别忘了给我点赞:)
    • 不幸的是,我的声望不到 15(悲伤的脸),所以我不能投票赞成/反对。当我确实有代表时,我会确保回到这篇文章并对其进行投票。
    • 干杯!我忘了他们有这个限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    相关资源
    最近更新 更多